一、Android应用程序注册广播接收器(registerReceiver)的过程分析

参考Android应用程序注册广播接收器(registerReceiver)的过程分析http://blog.csdn.net/luoshengyang/article/details/6737352和《Android系统源代码情景分析》,作者罗升阳。

0、总图:



1、MainActivity和CounterService所在应用程序主线程向ActivityManagerService进程发送REGISTER_RECEIVER_TRANSACTION


如图:第一步

~/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 ActivityManagerNativeimplements 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 ActivityManagerNativeimplements 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,具体调用如下,返回的是IInterfaceif (((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 implementsandroid.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");  }    }......  }

更多相关文章

  1. 类和 Json对象
  2. android 调用相机拍照 并缩放切割图片
  3. Android(安卓)Bundle类
  4. Android--用Pull解析器将对象解析成xml文件及单元测试
  5. Android之Input子系统事件分发流程
  6. Xposed: 勾住(Hook) Android应用程序对象的方法,实现AOP
  7. android:exported的用法
  8. Java工程中调用Android库出现“Stub!”错误
  9. 原文:Android(安卓)Theme XML

随机推荐

  1. 如何构建一个完整的To B应用开发平台
  2. 《世界前200名顶尖计量经济学家》,计量经
  3. 2020年要做的几件大事
  4. 六成开发者日编程不足4小时,半数认为学习
  5. 汉森的研究反省:充分利用数据来对经济建模
  6. 中国首个官方推出的开源协议:木兰宽松许可
  7. 开源分布式跟踪方案概览
  8. 百万年薪挖了个P8程序员,难道是“水货”?
  9. 想要改变世界的 Rust 语言
  10. “Python太慢了、Golang糟透了、MongoDB