11.4. 发送广播
11.4.发送广播
最后,为触发这个事件,我们需要广播一条能够匹配filter的Intent。前面的BootReceiver只管接收来自系统的广播,也就没必要负责发送Intent。但对TimelineReceiver来说,它接收的广播是来自应用程序本身,发送Intent也就需要我们自己负责了。
在第八章 Service 中,我们为UpdaterService创建了一个内部类Updater,负责在独立的线程中连接到服务端并抓取数据。第一手数据在它手里,因此由它负责发送通知是合理的。
例 11.7. UpdaterService.java, 内部类Updater
...
private class Updater extends Thread {
Intent intent;
public Updater() {
super("UpdaterService-Updater");
}
@Override
public void run() {
UpdaterService updaterService = UpdaterService.this;
while (updaterService.runFlag) {
Log.d(TAG, "Running background thread");
try {
YambaApplication yamba =
(YambaApplication) updaterService.getApplication(); //
int newUpdates = yamba.fetchStatusUpdates(); //
if (newUpdates > 0) { //
Log.d(TAG, "We have a new status");
intent = new Intent(NEW_STATUS_INTENT); //
intent.putExtra(NEW_STATUS_EXTRA_COUNT, newUpdates); //
updaterService.sendBroadcast(intent); //
}
Thread.sleep(60000); //
} catch (InterruptedException e) {
updaterService.runFlag = false; //
}
}
}
}
...
- 获取Application对象的引用。
- 前面我们曾在Application对象中实现了fetchStatusUpdates()方法,用以获取数据并写入数据库,并将获取数据的数量作为返回值返回。
- 检查是否得到新数据。
- 初始化Intent。NEW_STATUS_INTENT是一个常量,表示一项Action。在这里,它就是"com.marakana.yamba.NEW_STATUS"。Android并没有限制Action的名字,不过按照约定,一般都在它名字的前面加上package的名字。
- 可以为Intent添加附加数据。在这里,通知他人新得到数据的数目是有意义的。因此通过putExtra()方法将一个数值加入Intent,并与一个键值(NEW_STATUS_EXTRA_COUNT)关联起来。
- 我们已经确定得到了新数据,接下来就是将Intent广播出去。sendBroadcast()是个Context对象中的方法,而Service是Context的子类,因此也可以通过updaterService对象来调用sendBroadcast()。传入的参数就是刚刚创建的Intent。
- 让线程休眠一分钟,避免CPU过载。
- 如果线程被任何原因中断,则设置runFlag为false,表示Service已停止运行。
Note:
UpdaterService会持续广播着Intent,而不受TimelineReceiver影响。如果TimelineReceiver未被注册,则UpdaterService广播的Intent会被简单忽略。
到这里,UpdaterService会在每次收到新数据时广播一条Intent。TimelineReceiver则可以接收到这些Intent,并更新TimelineActivity所显示的内容。