Android应用程序的Java技术盛宴3
来源:互联网 发布:淘宝女人 编辑:程序博客网 时间:2024/04/28 07:38
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进行数据库访问
- public class StocksDb {
- private static final String DB_NAME = "stocks.db";
- private static final int DB_VERSION = 1;
- private static final String TABLE_NAME = "stock";
- private static final String CREATE_TABLE = "CREATE TABLE " +
- TABLE_NAME + " (id INTEGER PRIMARY KEY, symbol TEXT, max_price DECIMAL(8,2), " +
- "min_price DECIMAL(8,2), price_paid DECIMAL(8,2), " +
- "quantity INTEGER)";
- private static final String INSERT_SQL = "INSERT INTO " + TABLE_NAME +
- " (symbol, max_price, min_price, price_paid, quantity) " +
- "VALUES (?,?,?,?,?)";
- private static final String READ_SQL = "SELECT id, symbol, max_price, " +
- "min_price, price_paid, quantity FROM " + TABLE_NAME;
- private final Context context;
- private final SQLiteOpenHelper helper;
- private final SQLiteStatement stmt;
- private final SQLiteDatabase db;
- public StocksDb(Context context){
- this.context = context;
- helper = new SQLiteOpenHelper(context, DB_NAME, null,
- DB_VERSION){
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(CREATE_TABLE);
- }
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion,
- int newVersion) {
- throw new UnsupportedOperationException();
- }
- };
- db = helper.getWritableDatabase();
- stmt = db.compileStatement(INSERT_SQL);
- }
- public Stock addStock(Stock stock){
- stmt.bindString(1, stock.getSymbol());
- stmt.bindDouble(2, stock.getMaxPrice());
- stmt.bindDouble(3, stock.getMinPrice());
- stmt.bindDouble(4, stock.getPricePaid());
- stmt.bindLong(5, stock.getQuantity());
- int id = (int) stmt.executeInsert();
- return new Stock (stock, id);
- }
- public ArrayList<Stock> getStocks() {
- Cursor results = db.rawQuery(READ_SQL, null);
- ArrayList<Stock> stocks =
- new ArrayList<Stock>(results.getCount());
- if (results.moveToFirst()){
- int idCol = results.getColumnIndex("id");
- int symbolCol = results.getColumnIndex("symbol");
- int maxCol = results.getColumnIndex("max_price");
- int minCol = results.getColumnIndex("min_price");
- int priceCol = results.getColumnIndex("price_paid");
- int quanitytCol = results.getColumnIndex("quantity");
- do {
- Stock stock = new Stock(results.getString(symbolCol),
- results.getDouble(priceCol),
- results.getInt(quanitytCol),
- results.getInt(idCol));
- stock.setMaxPrice(results.getDouble(maxCol));
- stock.setMinPrice(results.getDouble(minCol));
- stocks.add(stock);
- } while (results.moveToNext());
- }
- if (!results.isClosed()){
- results.close();
- }
- return stocks;
- }
- public void close(){
- helper.close();
- }
- }
清单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.在一个单独的线程上插入数据库
- Button button = (Button) findViewById(R.id.btn);
- button.setOnClickListener(new OnClickListener(){
- public void onClick(View v) {
- String symbol = symbolIn.getText().toString();
- symbolIn.setText("");
- double max = Double.parseDouble(maxIn.getText().toString());
- maxIn.setText("");
- double min = Double.parseDouble(minIn.getText().toString());
- minIn.setText("");
- double pricePaid =
- Double.parseDouble(priceIn.getText().toString());
- priceIn.setText("");
- int quantity = Integer.parseInt(quantIn.getText().toString());
- quantIn.setText("");
- Stock stock = new Stock(symbol, pricePaid, quantity);
- stock.setMaxPrice(max);
- stock.setMinPrice(min);
- new AsyncTask<Stock,Void,Stock>(){
- @Override
- protected Stock doInBackground(Stock... newStocks) {
- // There can be only one!
- return db.addStock(newStocks[0]);
- }
- @Override
- protected void onPostExecute(Stock s){
- addStockAndRefresh(s);
- }
- }.execute(stock);
- }
- });
您可以先为按钮创建一个实践监听器。当用户点击按钮时,您可以从各个小部件(确切地说是EditText小部件)读取股票数据并填入一个新的Stock对象。您可以创建一个AsyncTask,并通过doInBackground方法从清单5中调用addStock方法。如此,addStock将在一个背景线程上执行,而不是在主UI线程上。完成之后,将新Stock对象从数据库传递到在主UI线程上执行的addStockAndRefresh方法。
- Android应用程序的Java技术盛宴3
- 享受Android应用程序的Java技术盛宴
- 享受Android应用程序的Java技术盛宴
- 享受Android应用程序的Java技术盛宴
- 享受Android应用程序的Java技术盛宴
- 享受Android应用程序的Java技术盛宴
- 享受 Android 应用程序的 Java 技术盛宴
- 享受Android应用程序的Java技术盛宴
- 享受Android应用程序的Java技术盛宴(转)
- Android应用程序的Java技术
- |转| Java的盛宴
- 开阔视野的技术盛宴
- Android应用程序的Java技术2
- 应用程序商店:难以下咽的盛宴
- 整合时代的技术盛宴 -IBM 2004开发者大会
- 书评:Java的盛宴(上)-Java基础-Java-编程开发
- 书评:Java的盛宴(中)-Java基础-Java-编程开发
- 书评:Java的盛宴(下)-Java基础-Java-编程开发
- struts2地址映射
- 产品的思路——来自腾讯张小龙的分享(全版)
- 基于信号量机制的进程同步问题模拟程序
- Intel、AMD和ARM混战 CPU上演三国演义
- ubuntu下ffmpeg编译安装
- Android应用程序的Java技术盛宴3
- 端口0-300
- flex运行浏览器的设置
- Android应用程序的Java技术
- Java中Native关键字的作用(转)
- AMD+ARM=更加精彩纷呈的未来
- Android应用程序的Java技术2
- Oracle中TO_DATE格式
- 一个简单的FreeMarker案例