11.4. 发送广播

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

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; //

}

}

}

}

...

  1. 获取Application对象的引用。
  2. 前面我们曾在Application对象中实现了fetchStatusUpdates()方法,用以获取数据并写入数据库,并将获取数据的数量作为返回值返回。
  3. 检查是否得到新数据。
  4. 初始化Intent。NEW_STATUS_INTENT是一个常量,表示一项Action。在这里,它就是"com.marakana.yamba.NEW_STATUS"。Android并没有限制Action的名字,不过按照约定,一般都在它名字的前面加上package的名字。
  5. 可以为Intent添加附加数据。在这里,通知他人新得到数据的数目是有意义的。因此通过putExtra()方法将一个数值加入Intent,并与一个键值(NEW_STATUS_EXTRA_COUNT)关联起来。
  6. 我们已经确定得到了新数据,接下来就是将Intent广播出去。sendBroadcast()是个Context对象中的方法,而Service是Context的子类,因此也可以通过updaterService对象来调用sendBroadcast()。传入的参数就是刚刚创建的Intent。
  7. 让线程休眠一分钟,避免CPU过载。
  8. 如果线程被任何原因中断,则设置runFlag为false,表示Service已停止运行。

Note:

UpdaterService会持续广播着Intent,而不受TimelineReceiver影响。如果TimelineReceiver未被注册,则UpdaterService广播的Intent会被简单忽略。

到这里,UpdaterService会在每次收到新数据时广播一条Intent。TimelineReceiver则可以接收到这些Intent,并更新TimelineActivity所显示的内容。