zoukankan      html  css  js  c++  java
  • 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");  
    		}    
    	}
    
    	......  
    
    }

  • 相关阅读:
    《css世界》学习摘要
    微信小程序知识点积累
    事件冒泡 事件委派
    遍历后台返回数据
    初识open stack
    keystone初识
    KVM详解
    openstack详解
    NoSQL之Redis集群理论
    gfs分布式文件系统
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6795396.html
Copyright © 2011-2022 走看看