Android应用程序的Java技术盛宴3

本文介绍如何在Android应用中使用SQLite数据库存储股票信息。通过创建一个数据库帮助类,实现股票数据的增删改查功能。文章还展示了如何利用AsyncTask在后台线程执行数据库操作,避免阻塞UI。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android数据库连通性

Android中一个非常有用的特征就是存在本地关系数据库。保证您能在本地文件中存储您的数据,但通常更有用的是使用一个关系型数据库管理系统(RelationalDatabaseManagementSystem,RDBMS)来存储。Android提供给您常用的SQLite数据库来进行处理,因为对于像Android这类嵌入式系统它是高度优化的。它被Android上的核心应用程序所用。例如,用户地址簿是存储在一个SQLite数据库中。现在,对于给定的Android的Java实现,您可以使用JDBC来访问这些数据库。出人意料的是,Android甚至包括构成主要部分JDBC API的java.sql和javax.sql包。然而,当涉及使用本地Android数据库进行处理时,这毫无用处。相反地,您想要使用android.database和android.database.sqlite包。清单5是一个使用这些类存储和检索数据的示例。

清单5.使用Android进行数据库访问

 
  1. publicclassStocksDb{
  2. privatestaticfinalStringDB_NAME="stocks.db";
  3. privatestaticfinalintDB_VERSION=1;
  4. privatestaticfinalStringTABLE_NAME="stock";
  5. privatestaticfinalStringCREATE_TABLE="CREATETABLE"+
  6. TABLE_NAME+"(idINTEGERPRIMARYKEY,symbolTEXT,max_priceDECIMAL(8,2),"+
  7. "min_priceDECIMAL(8,2),price_paidDECIMAL(8,2),"+
  8. "quantityINTEGER)";
  9. privatestaticfinalStringINSERT_SQL="INSERTINTO"+TABLE_NAME+
  10. "(symbol,max_price,min_price,price_paid,quantity)"+
  11. "VALUES(?,?,?,?,?)";
  12. privatestaticfinalStringREAD_SQL="SELECTid,symbol,max_price,"+
  13. "min_price,price_paid,quantityFROM"+TABLE_NAME;
  14. privatefinalContextcontext;
  15. privatefinalSQLiteOpenHelperhelper;
  16. privatefinalSQLiteStatementstmt;
  17. privatefinalSQLiteDatabasedb;
  18. publicStocksDb(Contextcontext){
  19. this.context=context;
  20. helper=newSQLiteOpenHelper(context,DB_NAME,null,
  21. DB_VERSION){
  22. @Override
  23. publicvoidonCreate(SQLiteDatabasedb){
  24. db.execSQL(CREATE_TABLE);
  25. }
  26. @Override
  27. publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,
  28. intnewVersion){
  29. thrownewUnsupportedOperationException();
  30. }
  31. };
  32. db=helper.getWritableDatabase();
  33. stmt=db.compileStatement(INSERT_SQL);
  34. }
  35. publicStockaddStock(Stockstock){
  36. stmt.bindString(1,stock.getSymbol());
  37. stmt.bindDouble(2,stock.getMaxPrice());
  38. stmt.bindDouble(3,stock.getMinPrice());
  39. stmt.bindDouble(4,stock.getPricePaid());
  40. stmt.bindLong(5,stock.getQuantity());
  41. intid=(int)stmt.executeInsert();
  42. returnnewStock(stock,id);
  43. }
  44. publicArrayList<Stock>getStocks(){
  45. Cursorresults=db.rawQuery(READ_SQL,null);
  46. ArrayList<Stock>stocks=
  47. newArrayList<Stock>(results.getCount());
  48. if(results.moveToFirst()){
  49. intidCol=results.getColumnIndex("id");
  50. intsymbolCol=results.getColumnIndex("symbol");
  51. intmaxCol=results.getColumnIndex("max_price");
  52. intminCol=results.getColumnIndex("min_price");
  53. intpriceCol=results.getColumnIndex("price_paid");
  54. intquanitytCol=results.getColumnIndex("quantity");
  55. do{
  56. Stockstock=newStock(results.getString(symbolCol),
  57. results.getDouble(priceCol),
  58. results.getInt(quanitytCol),
  59. results.getInt(idCol));
  60. stock.setMaxPrice(results.getDouble(maxCol));
  61. stock.setMinPrice(results.getDouble(minCol));
  62. stocks.add(stock);
  63. }while(results.moveToNext());
  64. }
  65. if(!results.isClosed()){
  66. results.close();
  67. }
  68. returnstocks;
  69. }
  70. publicvoidclose(){
  71. helper.close();
  72. }
  73. }

清单5中的类完全封装了一个用于存储股票信息的SQLite数据库。因为您将要使用一个嵌入式数据库,不仅是您的应用程序要使用它,而且也要通过应用程序来创建它。您需要提供代码来创建该数据库。Android提供一个有用的抽象帮助类SQLiteOpenHelper。要完成这一操作,您需要扩展这个抽象类并提供代码通过使用onCreate方法创建您的数据库。当您有一个帮助程序实例时,就可以获取一个SQLiteDatabase实例,您可以用来执行任意SQL语句。您的数据库类有两个较为方便的方法。第一个是addStock,用于将新股票保存到数据库中。注意,您使用了一个SQLiteStatement实例,这类似于一个java.sql.PreparedStatement。需要注意的是,在您的类构造器中如何对其进行编译,使其在每次调用addStock时都能重复利用。在每个addStock调用中,SQLiteStatement的变量(INSERT_SQL字符串中的问号)必然要将数据传递给addStock。再一次强调,这类似于PreparedStatement,您可以从JDBC了解它。

另一个方法是getStocks。顾名思义,它从数据库中检索所有股票。注意,您再次使用一个SQL字符串,正如您在JDBC中所用的那样。您可以在SQLiteDatabase类上通过使用rawQuery方法来进行处理。这个类也有几个查询方法,让您可以不使用SQL直接查询数据库。所有这些方法都返回一个Cursor对象,和java.sql.ResultSet非常相似。您可以将Cursor移动到从数据库中返回的数据所在行,在每一行,您可以使用getInt、getString和其他的方法来检索您要查询的数据库中各列相关的值。再一次强调,这和ResultSet十分相似。也和ResultSet比较相似,当您完成操作之后,关闭Cursor也十分重要的。如果您没有关闭Cursors,那么可能会迅速地耗尽内存并导致您的应用程序崩溃。

查询本地数据库是一个比较慢的过程,特别是,如果您有多行数据或者您需要在多个表之间运行复杂的查询语句。然而,数据库查询或插入超过5秒且出现一个Application Not Responding对话框,这种情况不太可能发生,但是当您的数据库忙于读取和写入数据时,冻结您的UI是不明智的。当然,避免这种情况最好的办法是使用AsyncTask。清单6展示了这个示例。

清单6.在一个单独的线程上插入数据库

 
  1. Buttonbutton=(Button)findViewById(R.id.btn);
  2. button.setOnClickListener(newOnClickListener(){
  3. publicvoidonClick(Viewv){
  4. Stringsymbol=symbolIn.getText().toString();
  5. symbolIn.setText("");
  6. doublemax=Double.parseDouble(maxIn.getText().toString());
  7. maxIn.setText("");
  8. doublemin=Double.parseDouble(minIn.getText().toString());
  9. minIn.setText("");
  10. doublepricePaid=
  11. Double.parseDouble(priceIn.getText().toString());
  12. priceIn.setText("");
  13. intquantity=Integer.parseInt(quantIn.getText().toString());
  14. quantIn.setText("");
  15. Stockstock=newStock(symbol,pricePaid,quantity);
  16. stock.setMaxPrice(max);
  17. stock.setMinPrice(min);
  18. newAsyncTask<Stock,Void,Stock>(){
  19. @Override
  20. protectedStockdoInBackground(Stock...newStocks){
  21. //Therecanbeonlyone!
  22. returndb.addStock(newStocks[0]);
  23. }
  24. @Override
  25. protectedvoidonPostExecute(Stocks){
  26. addStockAndRefresh(s);
  27. }
  28. }.execute(stock);
  29. }
  30. });

您可以先为按钮创建一个实践监听器。当用户点击按钮时,您可以从各个小部件(确切地说是EditText小部件)读取股票数据并填入一个新的Stock对象。您可以创建一个AsyncTask,并通过doInBackground方法从清单5中调用addStock方法。如此,addStock将在一个背景线程上执行,而不是在主UI线程上。完成之后,将新Stock对象从数据库传递到在主UI线程上执行的addStockAndRefresh方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值