您的位置:首页 > 移动开发 > Android开发

剖析ActivityManagerService源码,了解广播接收和发送机制(二)

2017-06-23 20:51 441 查看

1.简介

“在安卓的广播机制中,用户自定义的Activity或自定义的子类BroadcastReceiver扮演着接收器的角色,Activity本身以及各类系统事件(如有电话拨入)也可以扮演广播发出者的角色。而其中,Android的Activity Manager Service无疑扮演着核心角色。总体上,安卓的广播采用的是订阅者、发布者的设计模式。”       

                                                                     ---来自本人第一篇博客《对android广播接收与发出机制的一些AMS以外的源码分析》
第一节,我们在AMS以外的部分,描述了广播接收和发送机制的原理,主要是一些初始化操作,第二节我们在AMS内部观察注册广播接收器机制的原理。

现在我们开始在AMS内部观察发送广播的原理。

2.发送广播

首先我们回顾一下第一节的一些内容。注册者线程的最后一步是向远程binder对象发送信息。具体细节已在上一节阐述过,这里略过。

发送信息的关键语句是ActivityManagerProxy,中的broadcastIntent方法:

public int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String[] requiredPermissions, int appOp, Bundle options, boolean serialized,
boolean sticky, int userId) throws RemoteException
{
..................................
mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);
.................................
}
即向远程发送的事务代码为:BROADCAST_INTENT_TRANSACTION。从上一节的经验来讲,我们可以直接跳到ActivityManagerNative的onTransact方法中

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
.................................
@Override
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();
int appOp = data.readInt();
boolean serialized = data.readInt() != 0;
boolean sticky = data.readInt() != 0;
int userId = data.readInt();
int res = broadcastIntent(app, intent, resolvedType, resultTo,
resultCode, resultData, resultExtras, perm, appOp,
serialized, sticky, userId);
reply.writeNoException();
reply.writeInt(res);
return true;
}

........................
return super.onTransact(code, data, reply, flags);
}
}


这里switch的多路选择给到case BROADCAST_INTENT_TRANSACTION。代码进行一些初始化操作后跳转到broadcastIntent方法中。程序便跳转到ActivityManagerService的broadcastIntent方法中,具体原因在上一节已讲明。代码如下:

public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
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, appOp, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}

然后就进行了细致的广播发送操作。作者介绍至此,broadcastIntentLocked的内容下一节进行阐述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息