一个成熟的应用或者系统框架应该是可以根据一角来分析出整体的;因此在Android系统方面也不例外;今天我通过追踪startActivity过程来分析一下Android的系统流程;首先我追踪到:Activity.java:
@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 {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
//重点在这里
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) {
mStartedActivity = true;
}
final View decor = mWindow != null ? mWindow.peekDecorView() : null;
if (decor != null) {
decor.cancelPendingInputEvents();
}
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
if (options != null && !isTopOfTask()) {
mActivityTransitionState.startExitOutTransition(this, options);
}
}
下面我们到 Instrumentation.java:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
//重点在这里
int result = ActivityManagerNative.getDefault()
.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) {
}
return null;
}
最终执行的是ActivityManagerNative.getDefault()的startActivity方法;因此我们进入到ActivityManagerNative.java中:
首先看定义:
public abstract class ActivityManagerNative extends Binder implements IActivityManager
也就是说ActivityManagerNative 是一个Binder对象;并且实现了IActivityManager接口定义的业务;也就是说ActivityManagerNative 本身是一个实行IActivityManager的binder;至于Binder和binder驱动有什么关系,我觉得应该是binder驱动的一个业务代理类而已。
后面进入
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
//获取到一个IBinde对象
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
//将其转化为IActivityManager 对象
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
从该方法可以知道,ActivityManagerNative.getDefault()也不过是将IBinder对象转化为一个IActivityManager 对象;因此我们重点关注ServiceManager.getService("activity");这句话的实现。
到ServiceManager.java中:
public static IBinder getService(String name) {
try {
//从缓存中获取
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
//重点看这句
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// 将BinderInternal.getContextObject()对象转化为IServiceManager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
进入到BinderInternal.java中:
public static final native IBinder getContextObject();
是一个本地方法;也就是说,最终的IBinder对象是从C/C++层转化而来的
我找到了对应的本地方法:
android_util_Binder.cpp文件:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
//从自己所在的进程中获取一个sp<IBinder>对象
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
//将获取到的本地sp<IBinder>对象转化为Java层的Object对象
return javaObjectForIBinder(env, b);
}
我们在进入ProcessState.cpp中分析一下:
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
//注意传递的参数值为0
return getStrongProxyForHandle(0);
}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one. See comment
// in getWeakProxyForHandle() for more info about this.
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
//handle==0的情况
if (handle == 0) {
// Special case for context manager...
// The context manager is the only object for which we create
// a BpBinder proxy without already holding a reference.
// Perform a dummy transaction to ensure the context manager
// is registered before we create the first local reference
// to it (which will occur when creating the BpBinder).
// If a local reference is created for the BpBinder when the
// context manager is not present, the driver will fail to
// provide a reference to the context manager, but the
// driver API does not return status.
//
// Note that this is not race-free if the context manager
// dies while this code runs.
//
// TODO: add a driver API to wait for context manager, or
// stop special casing handle 0 for context manager and add
// a driver API to get a handle to the context manager with
// proper reference counting.
Parcel data;
//测试binder的状态
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
//新建一个BpBinder
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
//返回
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
仔细分析上面的过程,Java层最终获取的是C++层的一个handle==0的BpBinder对象;
回忆一下binder驱动和Service_manager的原理;我们知道,Service_manager是一个服务,是binder驱动的管家;它里面负责记录所有的其他binder_service;它通过进入一个死循环来不停读取binder驱动的消息;然后调用binder驱动的处理机制来进行消息处理;因此可以将Service_manager看做是binder驱动的发动机。而service_manager本身的句柄值就是0;因此想要获取其他binder_service要根据名字通过service_manager来查询他们的句柄值;因为service_manager中保存了所有通过binder驱动注册的进程服务;我们在Java层看到传递的name=”activity”,因此这个服务的拥有者一定是在系统启动以后,启动的一个binder_service,其中注册的一个名字是activity;
通过这个过程,我们大概可以知道Android系统是以binder驱动为核心,Service_manager为发动机的一个系统架构;里面有许多的管理各类资源的binder_service服务进程;然后当应用想要获取某一个应用进程的服务时,可以通过该进程注册的名字找到该服务,然后进程服务的调用。系统开发人员为了方便开发者调用服务,因此会利用代理模式实现好多级别的代理;最终到应用开发者这里,就可以很方便的调用系统所提供的服务接口。这就是所谓的
客户端—-binder—-服务器模式;客户端负责收集需求,收集事件数据,服务器负责真正的数据处理;binder起中介作用和资源管理分配等作用。