没有合适的资源?快使用搜索试试~ 我知道了~
Android应用程序发送广播(sendBroadcast)的过程分析.doc
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 136 浏览量
2022-07-08
21:54:23
上传
评论
收藏 191KB DOC 举报
温馨提示
试读
22页
Android应用程序发送广播(sendBroadcast)的过程分析
资源推荐
资源详情
资源评论
Android 应用程序发送广播(sendBroadcast)的过程分析
前面我们分析了 Android 应用程序注册广播接收器的过程,这个过程只完成了万里长征的第
一步,接下来它还要等待 ActivityManagerService 将广播分发过来。ActivityManagerService
是如何得到广播并把它分发出去的呢?这就是本文要介绍的广播发送过程了。
广播的发送过程比广播接收器的注册过程要复杂得多了,不过这个过程仍然是以
ActivityManagerService 为中心。广播的发送者将广播发送到 ActivityManagerService,
ActivityManagerService 接收到这个广播以后,就会在自己的注册中心查看有哪些广播接收
器订阅了该广播,然后把这个广播逐一发送到这些广播接收器中,但是
ActivityManagerService 并不等待广播接收器处理这些广播就返回了,因此,广播的发送和
处理是异步的。概括来说,广播的发送路径就是从发送者到 ActivityManagerService,再从
ActivityManagerService 到接收者,这中间的两个过程都是通过 Binder 进程间通信机制来
完成的,因此,希望读者在继续阅读本文之前,对 Android 系统的 Binder 进程间通信机制
有所了解,具体可以参考 Android 进程间通信(IPC)机制 Binder 简要介绍和学习计划一文。
本文继续以 Android 系统中的广播(Broadcast)机制简要介绍和学习计划一文中所开
发的应用程序为例子,并且结合上文 Android 应用程序注册广播接收器(registerReceiver)
的过程分析的内容,一起来分析 Android 应用程序发送广播的过程。
回顾一下 Android 系统中的广播(Broadcast)机制简要介绍和学习计划一文中所开发
的应用程序的组织架构,MainActivity 向 ActivityManagerService 注册了一个
CounterService.BROADCAST_COUNTER_ACTION 类型的计数器服务广播接收器,计数
器服务 CounterService 在后台线程中启动了一个异步任务(AsyncTask),这个异步任务
负责不断地增加计数,并且不断地将当前计数值通过广播的形式发送出去,以便
MainActivity 可以将当前计数值在应用程序的界面线程中显示出来。
计数器服务 CounterService 发送广播的代码如下所示:
[java] view plaincopy
1. public class CounterService extends Service implements ICounterService {
2. ......
3.
4. public void startCounter(int initVal) {
5. AsyncTask<Integer, Integer, Integer> task = new AsyncTask<Integer, I
nteger, Integer>() {
6. @Override
7. protected Integer doInBackground(Integer... vals) {
8. ......
9. }
10.
11. @Override
12. protected void onProgressUpdate(Integer... values) {
13. super.onProgressUpdate(values);
14.
15. int counter = values[0];
16.
17. Intent intent = new Intent(BROADCAST_COUNTER_ACTION);
18. intent.putExtra(COUNTER_VALUE, counter);
19.
20. sendBroadcast(intent);
21. }
22.
23. @Override
24. protected void onPostExecute(Integer val) {
25. ......
26. }
27.
28. };
29.
30. task.execute(0);
31. }
32.
33. ......
34. }
在 onProgressUpdate 函数中,创建了一个 BROADCAST_COUNTER_ACTION 类型
的 Intent,并且在这里个 Intent 中附加上当前的计数器值,然后通过 CounterService 类的
成员函数 sendBroadcast 将这个 Intent 发送出去。CounterService 类继承了 Service 类,
Service 类又继承了 ContextWrapper 类,成员函数 sendBroadcast 就是从
ContextWrapper 类继承下来的,因此,我们就从 ContextWrapper 类的 sendBroadcast 函
数开始,分析广播发送的过程。
在继承分析广播的发送过程前,我们先来看一下广播发送过程的序列图,然后按照这
个序图中的步骤来一步一步分析整个过程。
点击查看大图
Step 1. ContextWrapper.sendBroadcast
这个函数定义在 frameworks/base/core/java/android/content/ContextWrapper.java 文
件中:
[java] view plaincopy
1. public class ContextWrapper extends Context {
2. Context mBase;
3.
4. ......
5.
6. @Override
7. public void sendBroadcast(Intent intent) {
8. mBase.sendBroadcast(intent);
9. }
10.
11. ......
12.
13. }
这里的成员变量 mBase 是一个 ContextImpl 实例,这里只简单地调用
ContextImpl.sendBroadcast 进一行操作。
Step 2. ContextImpl.sendBroadcast
这个函数定义在 frameworks/base/core/java/android/app/ContextImpl.java 文件中:
[java] view plaincopy
1. class ContextImpl extends Context {
2. ......
3.
4. @Override
5. public void sendBroadcast(Intent intent) {
6. String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()
);
7. try {
8. ActivityManagerNative.getDefault().broadcastIntent(
9. mMainThread.getApplicationThread(), intent, resolvedType, nu
ll,
10. Activity.RESULT_OK, null, null, null, false, false);
11. } catch (RemoteException e) {
12. }
13. }
14.
15. ......
16.
17. }
这里的 resolvedType 表示这个 Intent 的 MIME 类型,我们没有设置这个 Intent 的
MIME 类型,因此,这里的 resolvedType 为 null。接下来就调用 ActivityManagerService
的远程接口 ActivityManagerProxy 把这个广播发送给 ActivityManagerService 了。
Step 3. ActivityManagerProxy.broadcastIntent
这个函数定义在 frameworks/base/core/java/android/app/ActivityManagerNative.java
文件中:
[java] view plaincopy
1. class ActivityManagerProxy implements IActivityManager
2. {
3. ......
4.
5. public int broadcastIntent(IApplicationThread caller,
6. Intent intent, String resolvedType, IIntentReceiver resultTo,
7. int resultCode, String resultData, Bundle map,
8. String requiredPermission, boolean serialized,
9. boolean sticky) throws RemoteException
10. {
11. Parcel data = Parcel.obtain();
12. Parcel reply = Parcel.obtain();
13. data.writeInterfaceToken(IActivityManager.descriptor);
14. data.writeStrongBinder(caller != null ? caller.asBinder() : null);
15. intent.writeToParcel(data, 0);
16. data.writeString(resolvedType);
17. data.writeStrongBinder(resultTo != null ? resultTo.asBinder() : null)
;
18. data.writeInt(resultCode);
19. data.writeString(resultData);
20. data.writeBundle(map);
21. data.writeString(requiredPermission);
22. data.writeInt(serialized ? 1 : 0);
23. data.writeInt(sticky ? 1 : 0);
24. mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);
25. reply.readException();
26. int res = reply.readInt();
27. reply.recycle();
28. data.recycle();
29. return res;
30. }
31.
32. ......
33.
34. }
这里的实现比较简单,把要传递的参数封装好,然后通过 Binder 驱动程序进入到
ActivityManagerService 的 broadcastIntent 函数中。
Step 4. ctivityManagerService.broadcastIntent
这个函数定义在
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件
中:
剩余21页未读,继续阅读
资源评论
oligaga
- 粉丝: 50
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功