Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 系統廣播機制

Android 系統廣播機制

編輯:關於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,主要關注這兩個參數。

\


<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+ICAgICAgIMjnzbyjurXatv6yvaOsyqHC1GJpbmRlcl90cmFuc2FjdGlvbrSryuS5/bPMo6zS8s6qyc/D5tLRvq231s72uf3By6GjPC9wPgo8cD48YnI+CjwvcD4KPHA+ICAgICAgIMjnzbyjurXayP2yvTwvcD4KPHA+ICAgICAgIH4vQW5kcm9pZC9mcmFtZXdvcmtzL2Jhc2UvY29yZS9qYXZhL2FuZHJvaWQvYXBwPC9wPgo8cD4gICAgICAgLS0tLUFjdGl2aXR5TWFuYWdlck5hdGl2ZS5qYXZhPC9wPgo8cD48cHJlIGNsYXNzPQ=="brush: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 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為要傳遞的數據。

如圖:第四步

~/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. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved