Android 系统广播机制

一、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 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"); } } ...... }

相关文章