开始我们的沉淀之路,老罗的书中第二章讲的是Android HAL层的知识,而且直接自己实现了一个虚拟的freg驱动程序,后面的几节是分别从native、java层如何访问这个虚拟的驱动程序接口,我这里没有这样的环境,所以就不分析这节了,第三章的智能指针我对比8.0系统源码和老罗的书,基本修改很小,大家如果要学习的话,就直接看老罗的书吧,这也反映出一个问题,就是我们学到的知识肯定是有用的,老罗在自己博客下面回答博友的提问时也一直在强调这点,我们学过的、学会的知识不可能浪费,没有用,肯定是有用的,即使上层再如何变化,但是涉及到核心的东西,变化也是很小的。老罗书中的第四章讲的是Log驱动的实现,对比Log来说,我们一般也就是会使用就可以了,所以也不打算在这一章节上花时间。
那么我们就进入第五章--Binder进程间通信。这是最有分量的一节,难度也非常大,之前自己也看过老罗的Binder系列博客很久了,但是对其中的各各环节还是理解的不透,我们就从这里开始学习吧。
老罗分析Binder进程间通信的实现时,开始讲解了很多Binder的结构体,我个人讲不清这个,我就按照自己的思路来学吧。如果大家搞过应用层的开发,相信大家都很清楚,我们使用的最多的就是Activity,它的启动过程就是一个完整的Binder调用,那么我们就以这个过程为学习路线,来分析一下startActivity的过程中Application应用层是怎么通过Binder进程间通信调用到ActivityManagerServie当中的。
我们的入口函数当然就是Activity类的startActivity方法了。Activity类的startActivity方法实现很简单,就是直接调用两个参数的startActivity方法,此时传入的第二个参数options为空,该方法的实现如下:
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
按照我们正常的启动逻辑,第二个参数options为空,所以进入else分支,调用startActivityForResult来进一步处理,再次调用三个参数的同名方法,mParent变量一般为空,所以会进入第一个if分支,这里最重要的就是mInstrumentation.execStartActivity、mMainThread.sendActivityResult这两句逻辑了。mInstrumentation.execStartActivity这句就会进入到我们的目标,将Activity的启动数据封装完成后,通过binder机制发送到Server端,也就是ActivityManagerService;mMainThread.sendActivityResult这句在判断调用正常的情况下,通知应用主线程ActivityThread来处理启动后的结果,mMainThread是一个ActivityThread类型的成员变量,它是在当前的Activity启动成功后,通过应用程序主线程ActivityThread类的performLaunchActivity方法来赋值的。我们就追踪mInstrumentation.execStartActivity的实现就可以了。mInstrumentation是Activity类的成员变量,它的类型是Instrumentation,它有三个execStartActivity重名方法,而当前的调用是第四个参数为Activity类型的,该方法的实现如下:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
result = am.onStartActivity(intent);
}
if (result != null) {
am.mHits++;
return result;
} else if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
这个方法中最重要的就是最后的try/catch了,通过调用ActivityManager.getService().startActivity来启动目标Activity,然后调用checkStartActivityResult方法来检查启动结果。我们继续跟踪ActivityManager.getService().startActivity,它需要分两段来分析。
第一段调用ActivityManager.getService()来获取binder代理对象,它的实现如下:
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
IActivityManagerSingleton是ActivityManager类中类型为Singleton<IActivityManager>的静态成员变量,get()方法是单例模式Singleton来实现的,当调用get()方法时,就会执行范型 T 的create()方法,Singleton类的代码如下:
public abstract class Singleton<T> {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
ActivityManager这里以Context.ACTIVITY_SERVICE为key值获取到一个IBinder对象,然后调用IActivityManager.Stub.asInterface(b)进行转换,就会得到一个BinderProxy对象,IActivityManager.aidl文件经过编译后就会生成IActivityManager.java,但是源码中没有,我就自己写了一个ICameraService.aidl文件,然后生成对应的ICameraService.java,我们可以用它来对比分析一下,ICameraService.java源码如下:
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: D:\\Work\\Project\\workstudio\\CameraService\\app\\src\\main\\aidl\\com\\huawei\\camerase