一、多进程系统设计及意义
Android系统分为5层,不过Android一般岗位只关注上三层就够用了即:应用层、framework层、native层。
Android中的应用层和系统服务层不在同一个进程,系统服务在单独的进程中。
Android中不同的应用属于不同的进程中
Android应用和系统服务运行在不同的进程中是为了安全、稳定、及内存管理的原因,但应用和系统服务需要通信和分享数据。
优点
安全性:每个进程都可以单独运行,可以保证应用层对系统层的隔离。
稳定性:如果某个进程崩溃了不会导致其他进程崩溃
内存分配:如果某个进程已经不需要了,可以从能存中移除,并回收相应的内存。
以上优点都是将系统设计成多进程的原因,我们在开发App时,也可以根据需要将App也设计成多进程的,比如以下场景:
虚拟机分配给各个进程的运行内存是有限的,LMK也会优先回收对系统资源占用多的进程。
突破进程内存限制,如图库占用内存过多
功能稳定性:独立的通信进程保持长连接的稳定性(如:微信的消息推送功能跑在独立的进程)
规避系统内存泄漏:独立的webview进程阻隔内存泄漏导致的问题
隔离风险:对于不稳定的功能放入独立的进程,避免导致主进程崩溃
二、Android/Linux都有哪些进程间通信方式?Android为什么主要采用Binder作为进程间的通信方式?
内存共享
管道
消息队列
socket
binder
疑问1:共享内存和内存映射有什么区别?
共享内存可以直接创建,内存映射需要磁盘文件(匿名映射除外)
内存映射用于文件读写:当多个进程映射到同一个文件时,并且设置了MAP_SHARE,此时可以IPC,不过数据会写回磁盘,所以还是共享内存快。
疑问2:为什么binder通信要将数据拷贝到内核空间,再由内核空间和server端做内存映射,而不是client和server直接做内存映射?
答:有两点1是拷贝到内核会对uid和pid等进行身份检测,权限安全,2是有一次拷贝,这就是个单向操作,server端哪怕修改了内存映射中的数据,也不会影响到client端中的数据,保证数据安全。
各种方式对比
三、Binder通信模型(以请求系统服务为例如ActivityManagerService)
Android系统服务在启动后会将自己注册到ServiceManager,ServiceManager维护了一个表来存储各种系统服务的名字和binder(系统服务名和系统服务的binder(可理解为系统服务的句柄)是对应关系)。
客户度想要请求系统服务时,要向serviceManager中传对应的系统服务名来获取对应的系统服务Binder。
客户端有了系统服务的binder就可以通过Binder驱动向系统服务发送数据,从而完成了跨进程通信。
客户端向服务端发送的数据中会携带客户端的binder,这样服务端如果有数据需要返回给客户端,就可以通过客户端的binder来实现。
四、Binder是怎么创建的?
1.要讨论Binder是怎么创建的,需要先清楚Binder是什么?
在Android中我们所使用的Activity,Service等组件都需要和AMS通信,这种跨进程的通信都是通过Binder完成的。
机制:Binder是一种进程间的通信机制
驱动:Binder是一个虚拟物理设备驱动
应用层:Binder是一个能发起通信的Java类
Framework/native:Binder连接了Client、Server、ServiceManager和Binder驱动程序,形成一套C/S的通信架构
2.Binder是什么时候创建的呢?
在进程创建的时候,就准备了binder
以Service Manager进程为例:
//文件路径:frameworks\native\cmds\servicemanager\main.cpp
int main(int argc, char** argv) {
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
}
//此时要使用的binder驱动为 "/dev/binder"
const char* driver = argc == 2 ? argv[1] : "/dev/binder";
//初始化binder驱动
sp ps = ProcessState::initWithDriver(driver);
ps->setThreadPoolMaxThreadCount(0);
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
//实例化ServiceManager
sp manager = new ServiceManager(std::make_unique());
//将自身作为服务添加
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
//设置服务端Bbinder对象
IPCThreadState::self()->setTheContextObject(manager);
//设置称为binder驱动的context manager,称为上下文的管理者
ps->becomeContextManager(nullptr, nullptr);
//通过Looper epoll机制处理binder事务
sp looper = Looper::prepare(false /*allowNonCallbacks*/);
BinderCallback::setupTo(looper);
ClientCallbackCallback::setupTo(looper, manager);
while(true) {
looper->pollAll(-1);
}
// should not be reached
return EXIT_FAILURE;
}
五、Binder的使用
通常我们使用Binder并不是直接使用,因为Binder的使用较为复杂容易出问题,由此Android官方出了一个对Binder的封装框架即AIDL。
可以先看下AIDL的简单使用
通过AIDL文件生成的接口中,内部类Stub提供了服务端提供的服务的实现逻辑,Proxy是Stub的代理类,用于给客户端提供调用服务端Stub的句柄。在使用demo中也能看到AIDL文件在客户端和服务端中都要用到(且内容相同),但在客户端与服务端中使用的部分是不一样的,Proxy是给客户端使用的,Stub是服务端使用的,或者说Stub是服务端所持有的。(注意这个service不是我们自己的service而是AMS)
六、Binder跨进程传递数据的详细流程
上图概括出了从Activity要拿到我们自己service的Binder的过程,要经过8次跨进程通信
这里我们以上图中①处的从App进程到servicemanager进程获取AMS的IBinder的操作为例,来具体分析Binder跨进程通信的过程。其中会涉及servicemanager的启动流程相关的内容,不熟悉的小伙伴可以先看一下。
客户端发送请求数据到内核中的Binder驱动
//入口代码
Activity中调用startService()
//最终会调用到ContextImpl.java中的
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
// ActivityManager.getService() 就是本小节分析的重点,跨进程获取AMS的IBinder
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), user.getIdentifier());
...
}
// ActivityManager.java
@UnsupportedAppUsage
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton IActivityManagerSingleton =
new Singleton() {
@Override
protected IActivityManager create() {
//这里正式进入主题,这行代码大家都很熟悉吧
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
//ServiceManager.java
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
//缓存中到不到,走这里
return Binder.allowBlocking(rawGetService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
// name是一层层传递进来的,ACTIVITY_SERVICE = "activity"
private static IBinder rawGetService(String name) throws RemoteException {
final long start = sStatLogger.getTime();
//这里分为两步
// step1:getIServiceManager() 拿到servicemanager的IBinder
// step2:getService(name) 这一步就是跨进程通信了
final IBinder binder = getIServiceManager().getService(name);
...
return binder;
}
//----------------------先看step1:---------------------------
private static IServiceManager getIServiceManager() {
//不为空直接返回
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface( //注解1
Binder.allowBlocking(
BinderInternal.getContextObject() //注解2
)
);
return sServiceManager;
}
//先看注解2: BinderInternal.java
//是个native方法,由此进入native层源码
public static final native IBinder getContextObject();
//寻找getContextObject()对应对的native方法,了解过Android系统启动流程的小伙伴知道在启动zygote进程的
//时候(frameworks\base\cmds\app_process\app_main.cpp),有一个非常重要的步骤就是会进行一系列的jni方法注册,
//我们来具体看下
//main方法
int main(int argc, char* const argv[])
{
...
if (zygote) {
//启动运行时环境
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
}
//进入start() frameworks\base\core\jni\AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector& options, bool zygote)
{
...
if (startReg(env) < 0) { //注册JNI
ALOGE("Unable to register all android natives\n");
return;
}
...
}
int AndroidRuntime::startReg(JNIEnv* env)
{
...
// gRegJNI 是定义好的jni方法 相关的结构体数组,系统中所有需要动态加载的jni方法都在这了
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
...
return 0;
}
static const RegJNIRec gRegJNI[] = {
...
//这个也有一定的规律,我们要寻找的BinderProxy.transactNative()的包名就是android.os,它是binder相关的jni
REG_JNI(register_android_os_Binder),
...
}
// frameworks\base\core\jni\android_util_Binder.cpp 进入register_android_os_Binder这个方法
int register_android_os_Binder(JNIEnv* env)
{
if (int_register_android_os_Binder(env) < 0)
return -1;
if (int_register_android_os_BinderInternal(env) < 0) //在这个方法里注册BinderInternal.java中的native方法
return -1;
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
...
}
//看和java类对应上了吧
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
...
return RegisterMethodsOrDie(
env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
//重点在这里,这个数组中写死了java方法与native方法的对应关系,(jni动态注册)
static const JNINativeMethod gBinderInternalMethods[] = {
/* name, signature, funcPtr */
//android_os_BinderInternal_getContextObject就是我们要找的native方法
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
{ "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
{ "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
{ "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
{ "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
};
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);
//将b转成java中的对象
return javaObjectForIBinder(env, b); //注解3
}
//frameworks\native\libs\binder\ProcessState.cpp
sp ProcessState::getContextObject(const sp& /*caller*/)
{
sp context = getStrongProxyForHandle(0);
...
return context;
}
sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
...
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
IBinder* b = e->binder;
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
// //创建BpBinder并保存下来以便后面再次查找
//ServiceManager 服务比较特殊,其BBinder(服务)保存在IPCThreadState中(the_context_object),对应的handle 是0;
//ServiceManager的BBinder在每一个进程中的handle值都为0。因此,任何进程和ServiceManager进程的通信便不再需要事先获取它的代理对象,
//而只需要告诉Binder Driver:我需要和handle值为0的进程通信。Binder Driver便会自动将该进程的通信请求转发到ServiceManager进程。
b = BpBinder::create(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
}
...
}
//最终将servicemanager的BBinder的代理对象BpBinder返回了出去
return result;
}
//接下来看注解3处的流程,将得到的BpBinder转换成Java层使用的对象
// 将一个BpBinder对象(这是native中的类型)转换成java中的类型
jobject javaObjectForIBinder(JNIEnv* env, const sp& val)
{
...
//通过反射创建java 对应的BpBinder对象(BinderProxy)
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
...
}
//gBinderProxyOffsets.mClass就是反射创建对象的类型,它是在下面的方法中被赋值的
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
...
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
"(JJ)Landroid/os/BinderProxy;");
gBinderProxyOffsets.mSendDeathNotice =
GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
...
}
/**回到注解2处,我们知道BinderInternal.getContextObject() = BinderProxy对象
*实质上是servicemanager进程中创建的BBinder对象
* java层 | native层
*封装关系ServicemanagerProxy->BinderProxy->BpBinder == BBinder
*此时再来看注释1处,其实就是
*sServiceManager = ServiceManagerNative.asInterface(BinderProxy对象) //伪代码
**/
//ServiceManagerNative.java
public static IServiceManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// ServiceManager is never local
return new ServiceManagerProxy(obj);
}
//java层的servicemanager的IBinder代理类
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote; //BinderProxy
//熟悉AIDL的小伙伴应该知道,IServiceManager这个类就是通过IServiceManager.aidl文件生成的,下面会给出这个文件
mServiceManager = IServiceManager.Stub.asInterface(remote);
}
//注意,后面step2就是走到这个方法
public IBinder getService(String name) throws RemoteException {
// Same as checkService (old versions of servicemanager had both methods).
return mServiceManager.checkService(name);
}
private IBinder mRemote;
private IServiceManager mServiceManager; //IServiceManager.Stub.Proxy类型
}
//---------------------------step2----------------------------
/**回到step2处,
*private static IBinder rawGetService(String name) throws RemoteException {
final long start = sStatLogger.getTime();
//这里分为两步
// step1:getIServiceManager() 拿到servicemanager的IBinder
// step2:getService(name) 这一步就是跨进程通信了
//由上可知getIServiceManager() = ServiceManagerNative.ServiceManagerProxy对象
final IBinder binder = getIServiceManager().getService(name);
...
return binder;
}
**/
//getService(name)会调到ServiceManagerNative.ServiceManagerProxy.getService()
public IBinder getService(String name) throws RemoteException {
//mServiceManager是IServiceManager.Stub.Proxy类型的对象
return mServiceManager.checkService(name);
}
//为了方便分析,我们可以使用aidl工具将IserviceManager.aidl的java类生成出来:
//内容较多只截取当前需要的部分代码
public interface IServiceManager extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.IServiceManager
{
private static final java.lang.String DESCRIPTOR = "android.os.IServiceManager";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an android.os.IServiceManager interface,
* generating a proxy if needed.
*/
public static android.os.IServiceManager asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.os.IServiceManager))) {
return ((android.os.IServiceManager)iin);
}
return new android.os.IServiceManager.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
private static class Proxy implements android.os.IServiceManager
{
private android.os.IBinder mRemote; //BinderProxy
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public android.os.IBinder checkService(java.lang.String name) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
android.os.IBinder _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(name);
//_data中写入了我们传的那么参数,mRemote的类型是BinderProxy,TRANSACTION_checkService代表当前要跨进程执行的是checkService()这个函数
boolean _status = mRemote.transact(Stub.TRANSACTION_checkService, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().checkService(name);
}
_reply.readException();
_result = _reply.readStrongBinder();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public static android.os.IServiceManager sDefaultImpl;
}
static final int TRANSACTION_getService = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_checkService = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
//来到BinderProxy类的transact()
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
...
try {
//主线流程来到transactNative(),他是一个native方法,
final boolean result = transactNative(code, data, reply, flags);
if (reply != null && !warnOnBlocking) {
reply.addFlags(Parcel.FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT);
}
return result;
}
...
}
//由此将从java层调用到native层
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
//4.寻找transactNative()对应对的native方法,了解过Android系统启动流程的小伙伴知道在启动zygote进程的
//时候(frameworks\base\cmds\app_process\app_main.cpp),有一个非常重要的步骤就是会进行一系列的jni方法注册,
//我们来具体看下:
//main方法
int main(int argc, char* const argv[])
{
...
if (zygote) {
//启动运行时环境
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
}
//进入start() frameworks\base\core\jni\AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector& options, bool zygote)
{
...
if (startReg(env) < 0) { //注册JNI
ALOGE("Unable to register all android natives\n");
return;
}
...
}
int AndroidRuntime::startReg(JNIEnv* env)
{
...
// gRegJNI 是定义好的jni方法 相关的结构体数组,系统中所有需要动态加载的jni方法都在这了
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
...
return 0;
}
static const RegJNIRec gRegJNI[] = {
...
//这个也有一定的规律,我们要寻找的BinderProxy.transactNative()的包名就是android.os,它是binder相关的jni
REG_JNI(register_android_os_Binder),
...
}
// frameworks\base\core\jni\android_util_Binder.cpp 进入register_android_os_Binder这个方法
int register_android_os_Binder(JNIEnv* env)
{
if (int_register_android_os_Binder(env) < 0)
return -1;
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
if (int_register_android_os_BinderProxy(env) < 0) //android.os.BinderProxy中的jni方法
return -1;
...
}
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
//通过反射技术进行动态注册
...
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
//JNINativeMethod这个结构体封装了java方法与native方法的对应关系,及方法签名
static const JNINativeMethod gBinderProxyMethods[] = {
/* name, signature, funcPtr */
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
{"getExtension", "()Landroid/os/IBinder;", (void*)android_os_BinderProxy_getExtension},
};
//android_os_BinderProxy_transact就是我们要寻找的目标,当java层调用BinderProxy的transactNative(),就会调到这个native方法:
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
...
//这里就是将java层的BinderProxy对象转换为native层的BpBinder对象
IBinder* target = getBPNativeData(env, obj)->mObject.get();
...
//调用BpBinder的transact()
status_t err = target->transact(code, *data, reply, flags);
}
//进入transact() frameworks\native\libs\binder\BpBinder.cpp
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
...
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
...
}
//进入transact() frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
...
if (reply) {
err = waitForResponse(reply); //即我们跨进程执行的函数时有返回值的
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
}
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
...
while(1){
//读写binder驱动
if ((err=talkWithDriver()) < NO_ERROR) break;
}
}
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
...
//这里的ioctl就是系统操作了,这里完成的操作就是将用户空间的数据写到内核空间中的binder驱动中
ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr);
...
}
将binder驱动中的数据发送到服务端
在servicemanager进程启动流程中提到,在servicemanager启动后,注册了回调方法来监听binder驱动中是否有数据写入,并开启Looper等待处理客户端发送(写入)的数据,在上一节中已经将数据写到驱动中,接下来进入监听函数:
//文件路径 frameworks\native\cmds\servicemanager\main.cpp
class BinderCallback : public LooperCallback {
public:
// 当binder驱动发来消息后,就可以通过次函数接收处理了
int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
//处理消息
IPCThreadState::self()->handlePolledCommands();
return 1; // Continue receiving callbacks.
}
};
继续来看收到消息后的具体处理:
// frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::handlePolledCommands()
{
status_t result;
// 当读缓存中数据未消费完时,持续循环
do {
result = getAndExecuteCommand();
} while (mIn.dataPosition() < mIn.dataSize());
// 当我们清空执行完所有的命令后,最后处理BR_DECREFS和BR_RELEASE
processPendingDerefs();
flushCommands();
return result;
}
继续跟进:
status_t IPCThreadState::getAndExecuteCommand()
{
status_t result;
int32_t cmd;
// 从binder驱动中读写数据并写入mIn(理论来说此时写缓存dataSize为0,也就是只读数据)
result = talkWithDriver();
...
cmd = mIn.readInt32();
//执行读到的命令
result = executeCommand(cmd);
...
}
executeCommand()主要任务就是根据binder驱动中读出的命令去执行对应的操作:
status_t IPCThreadState::executeCommand(int32_t cmd)
{
switch ((uint32_t)cmd) {
...
//以本案例,是处理这个命令
case BR_TRANSACTION:
{
...
Parcel buffer;
//读取数据到缓冲区
//实例化了一个Parcel对象作为缓冲区,从binder_transaction_data中将实际数据读取出来
buffer.ipcSetDataReference(
reinterpret_cast(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
Parcel reply;
//对于ServiceManager的binder节点来说,是没有ptr的
if (tr.target.ptr) {
// We only have a weak reference on the target object, so we must first try to
// safely acquire a strong reference before doing anything else with it.
// 对于其他binder服务端来说,tr.cookie为本地BBinder对象指针
if (reinterpret_cast(
tr.target.ptr)->attemptIncStrong(this)) {
error = reinterpret_cast(tr.cookie)->transact(tr.code, buffer,
&reply, tr.flags);
reinterpret_cast(tr.cookie)->decStrong(this);
} else {
error = UNKNOWN_TRANSACTION;
}
} else { //对于serviceManager来说the_context_object就是BBinder对象,
//在main()中创建了ServiceManager对象并赋值给了the_context_object
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
...
}
break;
}
}
但我们在ServiceManager中并没有找到transact()方法,它定义在ServiceManager的父类BnServiceManager的父类Binder(Binder.cppframeworks\native\libs\binder\Binder.cpp)中:
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
...
//进到这里
default:
err = onTransact(code, data, reply, flags);
break;
}
...
return err;
}
而在它的子类中重写了onTransact(),来到BnServiceManager,但这个类不在AOSP中,而是通过
(frameworks\native\libs\binder\aidl\android\os\IserviceManager.aidl)生成的:
::android::status_t BnServiceManager::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
case ::android::IBinder::FIRST_CALL_TRANSACTION + 1 /* checkService */:
{
...
// 这里调用的是子类(即实现类 ServceManager)的checkService(0
::android::binder::Status _aidl_status(checkService(in_name, &_aidl_return));
...
}
break;
}
}
来到frameworks\native\cmds\servicemanager\ServiceManager.cpp
Status ServiceManager::getService(const std::string& name, sp* outBinder) {
*outBinder = tryGetService(name, true);
// returns ok regardless of result for legacy reasons
return Status::ok();
}
sp ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
auto ctx = mAccess->getCallingContext();
sp out;
Service* service = nullptr;
//在android系统初始化的时候,所有的系统服务启动后都会以键值对的方式注册(保存)到ServiceManager中的mNameToService集合中
//这里的name是我们从java层传递下来的Context.ACTIVITY_SERVICE = “activity”,他对应的是ActivityManagerService的Binder对象
if (auto it = mNameToService.find(name); it != mNameToService.end()) {
service = &(it->second);
if (!service->allowIsolated) {
uid_t appid = multiuser_get_app_id(ctx.uid);
bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
if (isIsolated) {
return nullptr;
}
}
out = service->binder;
}
if (!mAccess->canFind(ctx, name)) {
return nullptr;
}
if (!out && startIfNotFound) {
tryStartService(name);
}
if (out) {
// Setting this guarantee each time we hand out a binder ensures that the client-checking
// loop knows about the event even if the client immediately drops the service
service->guaranteeClient = true;
}
return out;
}
到此将AMS的Binder对象返回给了客户端,有了AMS的Binder对象就可以使用AMS提供的服务(功能)了。
下图画出了跨进程通信中每层的关键流程。
七、AIDL文件生成c++文件
#aidl程序 设置生成的语言 aidl文件路径 aidl文件 输出路径 头文件输出路径
#sdk/build-tools
aidl.exe --lang=cpp -I E:\src E:\src\test.aidl -o E:\dst --head_out E:\dst