11.3. TimelineReceiver

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

11.3.TimelineReceiver

目前,UpdaterService可以定期抓取最新的消息数据,但它无法通知TimelineActivity。因此Timeline界面仍不能做到即时更新。

为解决这一问题,我们将创建另一个BroadcastReceiver,使它作为TimelineActivity的内部类。

例 11.4. TimelineActivity.java,内部类TimelineReceiver

...

class TimelineReceiver extends BroadcastReceiver { //

@Override

public void onReceive(Context context, Intent intent) { //

cursor.requery(); //

adapter.notifyDataSetChanged(); //

Log.d("TimelineReceiver", "onReceived");

}

}

...

  1. 同前面一样,BroadcastReceiver都是以BroadcastReceiver作为基类。
  2. 唯一需要实现的方法是onReceive()。其中的代码会在Receiver被触发时执行。
  3. 通知cursor对象刷新自己。对此,只需调用requery()方法,重新执行它的上一次数据查询就可以了。
  4. 通知adapter对象,它的内部数据已经被修改。

要让Receiver正常工作,我们还需要将它注册。不过这里不像刚才的BootReceiver那样在Manifest文件中添加声明就好,我们需要动态地注册TimelineReceiver。因为TimelineReceiver仅在用户查看 Timeline 界面时才有意义,将它静态地注册到Manifest文件的话,会无谓地浪费资源。

例 11.5. TimelineActivity.java中的内部类TimelineReceiver

...

@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);

// Create the adapter

adapter = new TimelineAdapter(this, cursor);

listTimeline.setAdapter(adapter);

// Register the receiver

registerReceiver(receiver, filter); //

}

@Override

protected void onPause() {

super.onPause();

// UNregister the receiver

unregisterReceiver(receiver); //

}

...

  1. 在TimelineActivity进入 Running 状态时注册 Receiver 。前面在"Running状态"一节中曾提到,在Activity进入Running状态之前,肯定要经过onResume()。因此,这里是注册Receiver的好地方。
  2. 与之相对,Activity在进入Stopped状态之前,肯定会经过onPause()。可以在这里注销Receiver。

前面还剩一个filter对象没解释:它是一个IntentFilter的实例,用以过滤出Receiver感兴趣的事件。在这里,我们通过一条表示Action事件的字符串来初始化它。

例 11.6. TimelineActivity.java,修改后的 onCreate()

...

filter = new IntentFilter("com.marakana.yamba.NEW_STATUS"); //

...

  1. 创建IntentFilter的实例,以"com.marakana.yamba.NEW_STATUS"作为构造函数的参数,表示一条Action事件。在这里使用了一个字符串,以后可以将它定义成常量,方便在其它地方使用。