一、前言
最近看《Android开发艺术探索》大多涉及到源码解析,仅仅看书有点云里雾里,于是配合着源码一起看感觉清晰许多。网上很多推荐source insight看源码,下来之后体验感觉一般,还不如AS直接看。老罗有专门的源码查看教学,但是需要Linux(Ubuntu)/MAC机器,暂时没条件以后考虑(老罗讲的比较深入,值得长期跟)。总之还是在AS里看(求推荐),强烈推荐浏览本文时和着源码。
二、源码解析
1、startActivityForResult
启动activity的方法最后都会走到startActivityForResult里。
这里调用了Instrumentation的execStartActivity方法,我们直接跟进。
在Instrumentation里调用了ActivityManagerNative的getDefault()方法,getDefault返回了一个IActivityManager对象。
是一个单例对象,看到asInterface很熟悉(不熟悉的可以参考我的另一篇博客Android多进程IPC机制——binder原理探索)
IActivityManager其实就是binder接口,查看ActivityManagerNative代码发现他其实就是扮演正常IPC接口IActivityManager里的stub角色,这样的话需要一个实现这个stub接口的类来实现startActivity方法。
没错,他就是ActivityManagerService,我们进到startActivity,发现他直接丢给了startActivityAsUser,在里面又调用了ActivityStackSupervisor的startActivityMayWait方法,这里的跳转都很简单,我就不贴代码了。下面我们来看看startActivityMayWait。
final int startActivityMayWait(//参数省略) {
//我们只关心如何启动,部分检查判断代码省略,千万不要企图搞懂每一句代码的意思,有兴趣的话回头再过来看
int res = startActivityLocked(caller, intent, resolvedType, aInfo,voiceSession, voiceInteractor, resultTo, resultWho,requestCode, callingPid, callingUid, callingPackage,realCallingPid, realCallingUid, startFlags, options,componentSpecified, null, container, inTask);
}
这里调用了startActivityLocked,而startActivityLocked里面又调用了startActivityUncheckedLocked,这个方法非常长,当时我是看晕了。这里我贴上关键代码。
经过一系列判断,调用了resumeTopActivitiesLocked方法,resumeTopActivitiesLocked里转给了ActivityStack的resumeTopActivityLocked方法。(这里其实可能调用ActivityStack的startActivityLocked方法,不过最终都会走到resumeTopActivityLocked)。在resumeTopActivityLocked内部又调用自己的resumeTopActivityInnerLocked方法,然后又回调了ActivityStackSupervisor的startSpecificActivityLocked方法:
直接走到realStartActivityLocked里,然后又一次的IPC通信,接口是IApplicationThread
这里调用了接口的scheduleLaunchActivity方法,和上一次一样,我们找到实现类ApplicationThread(是ActivityThread的内部类),以及他的scheduleLaunchActivity方法:
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
这个方法把传过来的参数包装成ActivityClientRecord ,通过sendMessage传出去,我们来看看这个sendMessage。
这里调用了mH的sendMessage方法,mH其实就是一个handler,我们看他如何处理数据:
在里面调用了方法handleLaunchActivity。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//省略部分代码
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
if (!r.activity.mFinished && r.startsNotResumed) {
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
// part of stopping the activity.
if (r.isPreHoneycomb()) {
r.state = oldState;
}
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to pause activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
r.paused = true;
}
} else {
// If there was an error, for any reason, tell the activity
// manager to stop us.
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
// Ignore
}
}
}
终于,我们看见了activity的实例
Activity a = performLaunchActivity(r, customIntent);
在这个方法里调用了activity的attach,以及生命周期oncreate。其他生命周期在上面代码里实现。
到这里,我们就理通了Activity的启动过程,主要还是利用IPC传递信息。
最后我推荐大家看源码时一定要做笔记,可以的话最好画图来帮助自己理清思路,不然会完全懵逼的。我目前使用startUML来画时序图,下面贴一张图。
怎么样,看到这张图感觉是不是整个流程清晰无比了?
哈哈,最后最后求查看源码方式,AS虽然勉强可以,但是也会经常找不到类很蛋疼。