編輯:關於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(2)根據intent(裡面還包含數據),registeredReceivers創建BroadcastRecord對象,並加入mParallelBroadcasts中:registeredReceivers = null; registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
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);
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為要傳遞的數據。
如圖:第三步
~/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");
}
}
......
}
四大組件的工作過程探索(一)
四大組件的運行狀態: Android中的四大組件中除了BroadcastReceiver以外,其他三種組件都必須在Android Mainfrst中注冊。對於,Bro
Android編程動態加載布局實例詳解【附demo源碼】
本文實例講述了Android編程動態加載布局的方法。分享給大家供大家參考,具體如下:由於前段時間項目需要,需要在一個頁面上加載根據不同的按鈕加載不同的布局頁面,當時想到用
XML解析器
一、操作XML文檔概述1、如何操作XML文檔XML文檔也是數據的一種,對數據的操作也不外乎是“增刪改查”。也被大家稱之為“CRUD&r
Android studio下使用ShareSDK實現一鍵分享
首先新建了一個項目用來演示集成ShareSDK 下載好了ShareSDK之後,解壓sharesd