10.2.2. 创建TimelineActivity类

优质
小牛编辑
129浏览
2023-12-01

10.2.2.创建TimelineActivity类

我们已经有了一个布局文件,接下来创建TimelineActivity类。同其它文件一样,进入 Eclipse Package Explorer,右击 com.marakana.yamba 包,选择New→Class,在名字一栏输入TimelineActivity。

同前面一样,我们创建的类只要是基本构件,无论是 Activity、Service、Broadcast Reciever 还是 Content Provider,都是基于 Android 框架中的基类继承出来的子类。对Activity而言,其基类即Activity。

我们通常会为每个 Activity 实现一个onCreate()方法 ,这是初始化数据库的好地方。与之对应,我们在onDestroy()方法 中清理onCreate()中创建的资源,也就是关闭数据库。我们希望显示的消息尽可能最新,因此把查询数据库的代码放在onResume()方法中,这样在界面每次显示时都会执行。代码如下:

package com.marakana.yamba5;

import android.app.Activity;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import android.os.Bundle;

import android.widget.TextView;

public class TimelineActivity1 extends Activity { //

DbHelper dbHelper;

SQLiteDatabase db;

Cursor cursor;

TextView textTimeline;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.timeline);

// Find your views

textTimeline = (TextView) findViewById(R.id.textTimeline);

// Connect to database

dbHelper = new DbHelper(this); //

db = dbHelper.getReadableDatabase(); //

}

@Override

public void onDestroy() {

super.onDestroy();

// Close the database

db.close(); //

}

@Override

protected void onResume() {

super.onResume();

// Get the data from the database

cursor = db.query(DbHelper.TABLE, null, null, null, null, null,

DbHelper.C_CREATED_AT + " DESC"); //

startManagingCursor(cursor); //

// Iterate over all the data and print it out

String user, text, output;

while (cursor.moveToNext()) { //

user = cursor.getString(cursor.getColumnIndex(DbHelper.C_USER)); //

text = cursor.getString(cursor.getColumnIndex(DbHelper.C_TEXT));

output = String.format("%s: %s\n", user, text); //

textTimeline.append(output); //

}

}

}

  1. 这是个Activity,因此继承自Android框架提供的Activity类。
  2. 我们需要访问数据库以得到Timeline的相关数据,而onCreate()正是连接数据库的好地方。
  3. 通过dbHelper打开数据库文件之后,我们需要它的getReadableDatabase()或getWritableDatabase()才可以得到实际的数据库对象。在这里我们只需读取Timeline的相关数据,因此按只读方式打开数据库。
  4. 我们得记着关闭数据库并释放资源。数据库是在onCreate()中打开,因此可以在onDestroy()中关闭。注意onDestroy()只有在系统清理资源时才被调用。
  5. 调用query()方法从数据库中查询数据,返回一个Cursor对象作为迭代器。参数似乎多的过了头,不过几乎都是对应着SQL的SELECT语句的各个部分。在这里也就相当与SELECT * FROMtimeline ORDER BY created_at DESC。这些null表示我们并没有使用SQL语句中相应的部分,比如WHERE,GROUPING, 与HAVING等。
  6. startManagingCursor()用于提示Activity自动管理Cursor的生命周期,使之同自己保持一致。“保持一致”的意思是,它能保证在Activity销毁时,同时释放掉Cursor关联的数据,这样有助于优化垃圾收集的性能。如果没有自动管理,那就只能在各个方法中添加代码,手工地管理Cursor了。
  7. cursor——回忆下Cursors一节的内容——即通过query()方法查询数据库所得的结果。按照表的形式,暂存多行多列的数据。每一行都是一条独立的记录——比如Timeline中的一条消息——而其中的列则都是预先定义的,比如_id,created_at,user以及txt。前面提到Cursor是个迭代器,我们可以通过它在每次迭代中读取一条记录,而在没有剩余数据时退出迭代。
  8. 对于 cursor 的当前记录,我们可以通过类型与列号来获取其中的值。由此,cursor.getString(3)返回一个字符串,表示消息的内容;cursor.getLong(1)返回一个数值,表示消息创建时的时间戳。但是,把列号硬编码在代码中不是个好习惯,因为数据库的原型一旦有变化,我们就不得不手工调整相关的代码,而且可读性也不好。更好的方法是,使用列名——回想下,我们曾在第九章中定义过C_USER与C_TEXT等字符串——调用cursor.getColumnIndex()得到列号,然后再取其中的值。
  9. 使用String.format()对每行输出进行格式化。在这里我们选择使用TextView控件显示数据,因此只能显示文本,或者说有格式的文本。我们在以后的迭代中更新这里。
  10. 最后把新的一行追加到textTimeline的文本中,用户就可以看到了。

上面的方法对较小的数据集还没问题,但绝对不是值得推荐的好方法。更好的方法是使用 ListView ,正如下文所示——它可以绑定数据库,伸缩性更好的同时也更加高效。