探索Android应用开发(五)

android

android

学习目标:

  1. 完善数据库操作部分

学习目的:

  1. 掌握Android的数据库

学习收获:

所有的Android数据库都被存储在/data/data/<package_name>/databases路径下。默认情况下,所有的数据库都是私有的,只能被创建它的应用访问。要想在各个应用之间分享数据库,可以使用Content Provider。数据库设计是个很广泛的话题,但是在Android里,最佳实践仍旧是要高度关注的。特别是,当在资源受限的设备上创建数据库时,利用范式来减少数据冗余是很重要的。

ContentValues对象被用来向数据库表中插入新的行,每一个Content Values对象都表示一行。Android提供了在Acitivty中管理Cursor的机制,startManagingCursor方法把Cursor的生命期和父Activity生命期绑定在一起。当使用完Cursor后,只需要调用stopManagingCursor方法。

在设计数据库时,有这么两点应该特别注意:

  1. 文件(例如图片或音频)通常是不存放在数据库表中。实际上,使用字符串存储这个文件的路径,特别是URI。
  2. 如果没有严格的要求,强烈推荐所有的表应该包含一个自增长的字段,来惟一标示一行。如果你要使用Content Provider,那么唯一ID是强制的。

Adapter是一个架在数据和用户界面View之间的桥梁。ArrayAdapter和SimpleCursorAdapter是比较有用的adpter。

Android采用Sqlite作为数据库,但是这个数据库支持的类型有限,根据它的文档,可以知道其只支持INTEGER, REAL, TEXT, BLOB或者是NULL,注意了,没有时间/日期类型。

经过一番查阅,我们有两种方法可以解决,第一种就是把时间格式化成字符串,采用TEXT存储;第二种就是把时间转化成毫秒,采用INTEGER存储。这里倾向于采用第二种方式,因为第一种方式容易因为忘记了时间格式,造成读取的时候出错,采用第二种方式以后,不用担心这个问题。

解决了这个问题以后,另一个问题就会出现了。因为我们在数据库中存储的是INTEGER类型,造成了SimpleCursorAdapter读到 INTEGER,直接显示在视图上,这是一个非常不友好的问题。很无奈,视图层和数据层直接绑定,出现这个问题是一定的。幸好Android已经想到了这一点,它在SimpleCursorAdapter中提供了ViewBinder来处理这个问题。我们可以使用这个类,从Cursor中获取到数据以后,经过加工,然后再设定View的值。如下所示:

public class PurseViewBinder implements ViewBinder{
 
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        int conTimeIndex = cursor.getColumnIndexOrThrow(PurseDbAdapter.KEY_TIME);
        if (columnIndex == conTimeIndex) {
            long consumeTimeLong = cursor.getLong(conTimeIndex);
            Date date = new Date(consumeTimeLong);
            DateFormat formater = new SimpleDateFormat("yyyy-MM-dd hh:mm");
            String consumeStr = formater.format(date);
            TextView timeView = (TextView) view;
            timeView.setText(consumeStr);
            return true;
        } else{
            return false;
        }
    }
 
}

有了这个以后,我们就可以在SimpleCursorAdapter使用了,如下所示:

    private void fillData() {
        // Get all of the notes from database and create the item list
        cursor = adapter.fetchAll();
        this.startManagingCursor(cursor);
        // An array of column names that will be added to the Map associated with each item.
        String[] from = new String[]{PurseDbAdapter.KEY_ROWID,PurseDbAdapter.KEY_TYPE, PurseDbAdapter.KEY_MONEY, PurseDbAdapter.KEY_TIME};
        //The views that should display column in the "from" parameter. These should all be TextViews.
        int[] to = {R.id._id, R.id.type, R.id.money, R.id.consumeTime};
        // Now create an array adapter
        SimpleCursorAdapter listAdapter = new SimpleCursorAdapter(this, R.layout.notes_row, cursor, from, to);
        ViewBinder binder = new PurseViewBinder();
        listAdapter.setViewBinder(binder);
        this.setListAdapter(listAdapter);
    }

Leave a comment

Your comment