Android 系统广播机制
一、Android应用程序注冊广播接收器(registerReceiver)的过程分析
參考Android应用程序注冊广播接收器(registerReceiver)的过程分析http://blog.csdn.net/luoshengyang/article/details/6737352和《Android系统源码情景分析》,作者罗升阳。
0、总图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamx0eGdjeQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
1、MainActivity和CounterService所在应用程序主线程向ActivityManagerService进程发送REGISTER_RECEIVER_TRANSACTION
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamx0eGdjeQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
如图:第一步
~/Android/frameworks/base/core/java/android/app
----ActivityManagerNative.java
- class ActivityManagerProxy implements IActivityManager
- {
- ......
- public Intent registerReceiver(IApplicationThread caller,
- IIntentReceiver receiver,
- IntentFilter filter, String perm) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(caller != null ? caller.asBinder() : null);
- data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);
- filter.writeToParcel(data, 0);
- data.writeString(perm);
- mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);
- reply.readException();
- Intent intent = null;
- int haveIntent = reply.readInt();
- if (haveIntent != 0) {
- intent = Intent.CREATOR.createFromParcel(reply);
- }
- reply.recycle();
- data.recycle();
- return intent;
- }
- ......
- }
当中receiver为InnerReceiver对象,例如以下图。还要filter,主要关注这两个參数。
如图:第二步,省略binder_transaction传输过程,由于上面已经分析过了。
如图:第三步
~/Android/frameworks/base/core/java/android/app
----ActivityManagerNative.java
- public abstract class ActivityManagerNative extends Binder implements IActivityManager
- {
- ......
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- switch (code) {
- case REGISTER_RECEIVER_TRANSACTION:
- {
- data.enforceInterface(IActivityManager.descriptor);
- IBinder b = data.readStrongBinder();
- IApplicationThread app =
- b != null ?
- ApplicationThreadNative.asInterface(b) : null;
- b = data.readStrongBinder();
- IIntentReceiver rec
- = b != null ? IIntentReceiver.Stub.asInterface(b) : null;
- IntentFilter filter = IntentFilter.CREATOR.createFromParcel(data);
- String perm = data.readString();
- Intent intent = registerReceiver(app, rec, filter, perm);
- reply.writeNoException();
- if (intent != null) {
- reply.writeInt(1);
- intent.writeToParcel(reply, 0);
- } else {
- reply.writeInt(0);
- }
- return true;
- }
- .......
- }
rec为IIntentReceiver.Stub.Proxy对象,如上图所看到的。还要filter,主要关注这两个參数。
如图:第四步
~/Android/frameworks/base/services/java/com/android/server/am
----ActivityManagerService.java
- public final class ActivityManagerService extends ActivityManagerNative
- implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
- ......
- public Intent registerReceiver(IApplicationThread caller,
- IIntentReceiver receiver, IntentFilter filter, String permission) {
- synchronized(this) {
- ProcessRecord callerApp = null;
- if (caller != null) {
- callerApp = getRecordForAppLocked(caller);
- if (callerApp == null) {
- ......
- }
- }
- .......
- ReceiverList rl
- = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
- if (rl == null) {
- rl = new ReceiverList(this, callerApp,
- Binder.getCallingPid(),
- Binder.getCallingUid(), receiver);
- if (rl.app != null) {
- rl.app.receivers.add(rl);
- } else {
- ......
- }
- mRegisteredReceivers.put(receiver.asBinder(), rl);
- }
- BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
- rl.add(bf);
- ......
- mReceiverResolver.addFilter(bf);
- // Enqueue broadcasts for all existing stickies that match
- // this filter.
- if (allSticky != null) {
- ......
- }
- return sticky;
- }
- }
- ......
- }
主要做了下面几件事:
(1)依据receiver创建ReceiverList。
(2)依据filter和rl创建BroadcastFilter。
(3)mReceiver.addFilter(bf)。
二、Android应用程序发送广播(sendBroadcast)的过程分析
0、总图
1、MainActivity和CounterService所在应用程序主线程向ActivityManagerService进程发送BROADCAST_INTENT_TRANSACTION
如图:第一步
~/Android/frameworks/base/core/java/android/app
----ActivityManagerNative.java
- class ActivityManagerProxy implements IActivityManager
- {
- ......
- public int broadcastIntent(IApplicationThread caller,
- Intent intent, String resolvedType, IIntentReceiver resultTo,
- int resultCode, String resultData, Bundle map,
- String requiredPermission, boolean serialized,
- boolean sticky) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(caller != null ? caller.asBinder() : null);
- intent.writeToParcel(data, 0);
- data.writeString(resolvedType);
- data.writeStrongBinder(resultTo != null ? resultTo.asBinder() : null);
- data.writeInt(resultCode);
- data.writeString(resultData);
- data.writeBundle(map);
- data.writeString(requiredPermission);
- data.writeInt(serialized ? 1 : 0);
- data.writeInt(sticky ? 1 : 0);
- mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);
- reply.readException();
- int res = reply.readInt();
- reply.recycle();
- data.recycle();
- return res;
- }
- ......
- }
当中主要关注intent參数。
如图:第二步,省略binder_transaction传输过程。由于上面已经分析过了。
如图:第三步
~/Android/frameworks/base/core/java/android/app
----ActivityManagerNative.java
- public abstract class ActivityManagerNative extends Binder implements IActivityManager
- {
- ......
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- switch (code) {
- case BROADCAST_INTENT_TRANSACTION:
- {
- data.enforceInterface(IActivityManager.descriptor);
- IBinder b = data.readStrongBinder();
- IApplicationThread app =
- b != null ?
- ApplicationThreadNative.asInterface(b) : null;
- Intent intent = Intent.CREATOR.createFromParcel(data);
- String resolvedType = data.readString();
- b = data.readStrongBinder();
- IIntentReceiver resultTo =
- b != null ?
- IIntentReceiver.Stub.asInterface(b) : null;
- int resultCode = data.readInt();
- String resultData = data.readString();
- Bundle resultExtras = data.readBundle();
- String perm = data.readString();
- boolean serialized = data.readInt() != 0;
- boolean sticky = data.readInt() != 0;
- int res = broadcastIntent(app, intent, resolvedType, resultTo,
- resultCode, resultData, resultExtras, perm,
- serialized, sticky);
- reply.writeNoException();
- reply.writeInt(res);
- return true;
- }
- .......
- }
如图:第四步
~/Android/frameworks/base/services/java/com/android/server/am
----ActivityManagerService.java
- public final class ActivityManagerService extends ActivityManagerNative
- implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
- ......
- public final int broadcastIntent(IApplicationThread caller,
- Intent intent, String resolvedType, IIntentReceiver resultTo,
- int resultCode, String resultData, Bundle map,
- String requiredPermission, boolean serialized, boolean sticky) {
- synchronized(this) {
- intent = verifyBroadcastLocked(intent);
- final ProcessRecord callerApp = getRecordForAppLocked(caller);
- final int callingPid = Binder.getCallingPid();
- final int callingUid = Binder.getCallingUid();
- final long origId = Binder.clearCallingIdentity();
- int res = broadcastIntentLocked(callerApp,
- callerApp != null ? callerApp.info.packageName : null,
- intent, resolvedType, resultTo,
- resultCode, resultData, map, requiredPermission, serialized,
- sticky, callingPid, callingUid);
- Binder.restoreCallingIdentity(origId);
- return res;
- }
- }
- ......
- }
主要做了下面几件事:
(1)依据intent找出对应的广播接收器:
- List<BroadcastFilter> registeredReceivers = null;
- registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
(2)依据intent(里面还包括数据)。registeredReceivers创建BroadcastRecord对象,并增加mParallelBroadcasts中:
- BroadcastRecord r = new BroadcastRecord(intent, callerApp,
- callerPackage, callingPid, callingUid, requiredPermission,
- registeredReceivers, resultTo, resultCode, resultData, map,
- ordered, sticky, false);
- mParallelBroadcasts.add(r);
(3)依据r和从r中得到的BroadcastFilter(即上面注冊时的BroadcastFilter),调用deliverToRegisteredReceiverLocked:
- deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
(4)调用filter.receiverList.receiver和new Intent(r.intent)调用performReceiveLocked:
- performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
- new Intent(r.intent), r.resultCode,
- r.resultData, r.resultExtras, r.ordered, r.initialSticky);
(5)ActivityManagerService进程向MainActivity和CounterService所在应用程序子线程发送SCHEDULE_REGISTERED_RECEIVER_TRANSACTION
- app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
- data, extras, ordered, sticky);
当中receiver为IIntentReceiver.Stub.Proxy对象。intent为要传递的数据。
2、ActivityManagerService进程向MainActivity和CounterService所在应用程序子线程发送SCHEDULE_REGISTERED_RECEIVER_TRANSACTION
如图:第一步
~/Android/frameworks/base/core/java/android/app
----ApplicationThreadNative.java,ApplicationThreadProxy类
- class ApplicationThreadProxy implements IApplicationThread {
- ......
- public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
- int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky)
- throws RemoteException {
- Parcel data = Parcel.obtain();
- data.writeInterfaceToken(IApplicationThread.descriptor);
- data.writeStrongBinder(receiver.asBinder());
- intent.writeToParcel(data, 0);
- data.writeInt(resultCode);
- data.writeString(dataStr);
- data.writeBundle(extras);
- data.writeInt(ordered ?
- 1 : 0);
- data.writeInt(sticky ?
- 1 : 0);
- mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
- IBinder.FLAG_ONEWAY);
- data.recycle();
- }
- ......
- }
当中receiver为IIntentReceiver.Stub.Proxy对象,intent为要传递的数据。
如图:第二步,省略binder_transaction传输过程,由于上面已经分析过了。
如图:第三步
~/Android/frameworks/base/core/java/android/app
----ApplicationThreadNative.java
- public abstract class ApplicationThreadNative extends Binder
- implements IApplicationThread {
- ........
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- switch (code) {
- case SCHEDULE_REGISTERED_RECEIVER_TRANSACTION: {
- data.enforceInterface(IApplicationThread.descriptor);
- IIntentReceiver receiver = IIntentReceiver.Stub.asInterface(
- data.readStrongBinder());
- Intent intent = Intent.CREATOR.createFromParcel(data);
- int resultCode = data.readInt();
- String dataStr = data.readString();
- Bundle extras = data.readBundle();
- boolean ordered = data.readInt() != 0;
- boolean sticky = data.readInt() != 0;
- scheduleRegisteredReceiver(receiver, intent,
- resultCode, dataStr, extras, ordered, sticky);
- return true;
- }
- .......
- }
当中receiver为InnerReceiver。
intent为要传递的数据。
大家已经对,IIntentReceiver.Stub.asInterface( data.readStrongBinder())非常费解,data.readStrongBinder得到是InnerReceiver对象,那为什么要生成IIntentReceiver.Stub.Proxy的代理对象呢?事实上不然。绕了一圈,最后还是生成了InnerReceiver对象。
- public static android.content.IIntentReceiver asInterface(
- android.os.IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- android.os.IInterface iin = (android.os.IInterface) obj
- .queryLocalInterface(DESCRIPTOR);//假设是BinderProxy对象调用这种方法。返回的NULL。可是如今是InnerReceiver,详细调用例如以下,返回的是IInterface
- if (((iin != null) && (iin instanceof android.content.IIntentReceiver))) {
- return ((android.content.IIntentReceiver) iin);
- }
- return new android.content.IIntentReceiver.Stub.Proxy(obj);
- }
- public IInterface queryLocalInterface(String descriptor) {
- if (mDescriptor.equals(descriptor)) {
- return mOwner;
- }
- return null;
- }
如今是InnerReceiver,详细调用例如以下。返回的是IInterface。这个是在IIntentReceiver.Stub初始化时设置的。
- public interface IIntentReceiver extends android.os.IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements
- android.content.IIntentReceiver {
- private static final java.lang.String DESCRIPTOR = "android.content.IIntentReceiver";
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
如图:第四步
~/Android/frameworks/base/core/java/android/app
----ActivityThread.java
- public final class ActivityThread {
- ......
- private final class ApplicationThread extends ApplicationThreadNative {
- ......
- // This function exists to make sure all receiver dispatching is
- // correctly ordered, since these are one-way calls and the binder driver
- // applies transaction ordering per object for such calls.
- public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
- int resultCode, String dataStr, Bundle extras, boolean ordered,
- boolean sticky) throws RemoteException {
- receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky);
- }
- ......
- }
- ......
- }
经过一系列折腾,最后在MainActivity和CounterService所在应用程序主线程运行:
- receiver.onReceive(mContext, intent);
运行onRecevice函数:
- public class MainActivity extends Activity implements OnClickListener {
- ......
- private BroadcastReceiver counterActionReceiver = new BroadcastReceiver(){
- public void onReceive(Context context, Intent intent) {
- int counter = intent.getIntExtra(CounterService.COUNTER_VALUE, 0);
- String text = String.valueOf(counter);
- counterText.setText(text);
- Log.i(LOG_TAG, "Receive counter event");
- }
- }
- ......
- }
Android 系统广播机制的更多相关文章
- Android系统广播机制存在漏洞,恶意软件可绕过安全机制跟踪用户
前言 国外研究人员披露了Android漏洞(CVE-2018-9489)的信息.Android系统的内部广播机制会暴露敏感的用户和设备信息,手机上安装的应用可在用户不知情或未经许可的情况下访问获取这些 ...
- Android系统广播处理机制
Android系统中的广播是广泛用于应用程序之间通信的一种手段,它类似于事件处理机制,不同的地方就是广播的处理是系统级别的事件处理过程(一般事件处理是控件级别的).在此过程中仍然是离不开Intent对 ...
- Android广播机制的深入学习
部分内容转载自http://www.cnblogs.com/lwbqqyumidi/p/4168017.html 1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者 ...
- Android总结篇系列:Android广播机制
1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通 ...
- Android广播机制概述
1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通 ...
- Android广播机制:Broadcast
转载:Android总结篇系列:Android广播机制 1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广 ...
- Android广播机制(转)
1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通 ...
- Android广播机制
原文出处: Android总结篇系列:Android广播机制 1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的 ...
- Android随笔之——Android广播机制Broadcast详解
在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理.这个广播跟我们传统意义中的电台广播有些相似之处.之所以叫做广播,就 ...
随机推荐
- JavaScript 基础:Babel 转译 class 过程窥探
零.前言 虽然在 JavaScript 中对象无处不在,但这门语言并不使用经典的基于类的继承方式,而是依赖原型,至少在 ES6 之前是这样的.当时,假设我们要定义一个可以设置 id 与坐标的类,我们会 ...
- java 之Thread线程相关yield()、sleep()、wait()、join()、run和start方法详解
1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...
- 解决windows管理员已阻止你运行此应用问题
按WIN+R键,打开“运行”,然后输入“gpedit.msc",就是打开组策略,这个在控制面板中也可以打开. 在组策略里找到“计算机配置”-“Windows设置”-“安全设置”-“本地策略” ...
- PAT Basic 1039
1039 到底买不买 小红想买些珠子做一串自己喜欢的珠串.卖珠子的摊主有很多串五颜六色的珠串,但是不肯把任何一串拆散了卖.于是小红要你帮忙判断一下,某串珠子里是否包含了全部自己想要的珠子?如果是,那么 ...
- Android开发——Activity启动模式详解
1. Activity的启动模式 本文原创,转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52054893 1.1 Standard标 ...
- Httpclient 和 HtmlUnit 对比
unit相比于client更接近浏览器,模拟浏览器访问状态,两者都是将网页封装成了一个对象,不同是,client能更好地操作网页元素. but 官方unit已经很老了,08年的,已经不更新了.
- localstorage与sessionstorage的使用
cookie,sessionStorage,localeStorage的区别 cookie是存储在浏览器端,并且随浏览器的请求一起发送到服务器端的,它有一定的过期时间,到了过期时间自动会消失.sess ...
- WordPress 编辑器没有可视化
第一次安装wordpress后出现文章编辑器只有一行按钮的问题,即使我安装了其他的编辑插件也是一样只有一行, 解决方法: 原来是再Users->All Users 中勾选了Disable the ...
- SPOJ GSS2 Can you answer these queries II ——线段树
[题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...
- bzoj 4401 块的计数 思想+模拟+贪心
块的计数 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 455 Solved: 261[Submit][Status][Discuss] Descr ...