关于Activity的源码分析,看了足足有半个月,理由就是:
1:Activity源代码很多,逻辑很复杂 2:下班再能加班学习,礼拜天抽空学习源码 至于为什么看源码:因为偶尔看到一句话:不懂Activity的onCreate的内部源码,你敢说你是Android开发程序猿?!其实关于这篇文章,我想了很久,不太敢贸然写,因为牵涉的类有点多并且复杂,怕理解出错,给各位小伙伴带来困扰,经过学习了两个礼拜,学到了一点东西,总结一下。
首先Activity的启动切入点有两个,startActivity切入和ActivityThread的main方法切入,最终的效果都是开启一个新的Activity。 本篇文章先从ActivityThread的main方法切入分析。 ActivityThread的Main方法入口通常我们启动一个App,首先都是先创建一个进程,然后AMS调度,进入到ActivityThread的main方法中,ActivityThread类通常就是我们说的UI线程(主线程),一个进程对应一个ActivityThread,用于调度Activity的生命周期,Service的生命周期,以及调度Instrumentation的创建。看下main源码:
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); SamplingProfilerIntegration.start();// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false);Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir);Process.setArgV0("<pre-initialized>");
//注意点1:创建主线程的Looper
Looper.prepareMainLooper();//创建ActivityThread类
ActivityThread thread = new ActivityThread(); //注意点2: thread.attach(false);if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler(); }if (false) {
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); }// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); //开始主线程消息调度 Looper.loop();//注意点3:不能够退出主线程Looper
throw new RuntimeException("Main thread loop unexpectedly exited"); }
通过Main方法,看下三个注意点:
创建主线程的Looper对象;在之前学习Handler,Looper源码的时候,没有初始化Looper,都能够实现消息调度。
调用了ActivityThread的attach方法 不能够退出主线程UI,如果如果退出,就报错,因为我们知道,开启looper消息循环之后,Looper.loop()之后的代码是不会执行的,因为如果退出了主线程,那么App自动就死了,所以就提示报错。进入ActivityThread的attach方法。
private void attach(boolean system) {
sCurrentActivityThread = this; mSystemThread = system; if (!system) { ViewRootImpl.addFirstDrawHandler(new Runnable() { public void run() { ensureJitEnabled(); } }); android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); //创建获得IActivityManager的代理对象ActivityManagerService final IActivityManager mgr = ActivityManager.getService(); try { //创建applicaiton mgr.attachApplication(mAppThread); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } .... }
先看下,ActivityManager.getService(),进入该方法:
public static IActivityManager getService() {
return IActivityManagerSingleton.get(); }//单例模式
private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { protected IActivityManager create() { //获取一个关联了系统服务ActivityManagerService的Binder对象 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); //获取IActivityManager的代理对象,基于binder机制,通过调用代理对象的方法,从而使ActivityManagerService对象的方法被调用. //注意:ActivityManagerService继承自IActivityManager.Stub。 final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
getService()内部调用的是IActivityManagerSingleton的get方法,大体来说,IActivityManagerSingleton是一个单例对象,再看onCreate方法,方法内部首先通过ServiceManager获得Activity_Service的注册服务。返回IBinder对象,至此,我们应该知道了,其实和底层交互数据的原理就是Binder机制。
先说下Binder机制,我们知道Binder机制由四部分组成:客户端,服务端,ServiceManager管理以及Binder驱动。其中前三个运行在用户层,Binder驱动运行在内核层,然后服务端实现IBinder方法,成为代理对象,底层的各种的ManagerService都会在ServiceManager,通过ServiceManager统一获得各种服务端Binder对象。至于Binder机制,建议各位同学去看下Binder源码。在此不再赘述。
我们知道ActivityManagerService继承字IActivityManager.Stub,所以本身来说他就是一个Binder对象。所以getService()方法本身返回的就是一个代理对象,通过调用代理对象的方法,从而调用AMS(ActivityManagerService的简称)的方法。
接下来回到attach方法,调用了AMS的attachApplication方法,源码示下:
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {......
if (app.instr != null) { thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial); } else { //通过代理对象ApplicationThread调用其方法bindApplication方法; thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial); }.....
// See if the top visible activity is waiting to run in this process...
if (normalMode) { try { //注意点2: if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } .... }首先看到上述代码:调用了thread.bindApplication(….)方法,thread是个IApplicationThread代理对象,又是Binder机制。。。实际上,AMS向上层UI主线程的控制是通过ApplicationThread的调度,ApplicaitonThread是ActivityThread的内部类,继承了IAppllication.Stub,是个Binder类,所以调用thread.bindApplicaiton(), 实际上调用的是ApplicationThread的bindApplication()方法; 至于注意点2: 我们下文再分析
进入到ApplicationThread $ bindApplication :
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableBinderTracking, boolean trackAllocation, boolean isRestrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map services, Bundle coreSettings, String buildSerial) {.....
sendMessage(H.BIND_APPLICATION, data); }发送Message, 继续跟进:handleBindApplication :
private void handleBindApplication(AppBindData data) {
....
//获取APK的相关信息,比如:包名,版本号等信息;
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);.....
//创建ContextImpl(该类继承自抽象类Context)
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); updateLocaleListFromAppContext(appContext, mResourcesManager.getConfiguration().getLocales());.....
// Continue loading instrumentation.
if (ii != null) { final ApplicationInfo instrApp = new ApplicationInfo(); ii.copyTo(instrApp); instrApp.initForUser(UserHandle.myUserId()); // 获取APP信息 final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);try {
final ClassLoader cl = instrContext.getClassLoader(); //注意点1:通过反射创建Instrumentation对象 mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); }......
try {
//注意点2:创建Application
Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app;.....
try {
//注意点3:调用Application的onCreate方法 mInstrumentation.callApplicationOnCreate(app); } ...... }
看下注意点:
通过反射创建Instrumentation对象,首先,对于Instrumentation的作用,先不深谈,我们只要知道创建Instrumentation的位置。
data.info.makeApplication(…) 这里data.info 也就是LoadedAPK类的对象。 调用了Instrumentation的callApplicationOnCreate方法。首先说下注意点看,进入到LoadedApk $ makeApplication(…)
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) { //整个应用内,只有一个Application对象 if (mApplication != null) { return mApplication; }Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) { appClass = "android.app.Application"; }try {
java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals("android")) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "initializeJavaContextClassLoader"); initializeJavaContextClassLoader(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } //调用Instrumentation的newApplication方法。 app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); }......
}
上述代码,首先判断mApplication是否为null, 不为null,就直接返回,这就是为什么一个应用只有一个Application对象(单进程), 为null的话,调用了Instrumentation的newApplication方法。
进入到Instrumentation $ newApplication方法static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException, ClassNotFoundException { //通过反射创建了Application对象 Application app = (Application)clazz.newInstance(); app.attach(context); return app; }
newApplication做的事只有两件,首先通过反射创建Application对象,并且调用其attach方法,返回该对象。再次注意一下:Application是在Instrumentation中创建的。
再回到ActivityThread的handleBindApplication方法,接下来看下注意点3:进入到Instrumentation $ callApplicationOnCreate方法:
public void callApplicationOnCreate(Application app) {
app.onCreate(); }调用了,就一句话:调用了Application的onCreate方法。
解释了:为什么我们一般都在Application的onCreate方法中初始化一些第三方,因为它最早被创建啊!至此Application的创建就完成了,那么Activity页面呢?
回到AMS的attachApplicationLocked方法:看下注意点2,调用了ActivityStackSupervisor类的attachApplicationLocked方法:
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {....
//
if (realStartActivityLocked(hr, app, true, true)) { didSomething = true; } .... }进入realStartActivityLocked(….)方法,
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {......
/*
通过binder机制,通过代理调用ApplicationThread的scheduleLaunchActivity方法。将启动Activity的操作交给ApplicationThread类 */ app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global and // override configs. mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);.......
}
调用了Application的ApplicationThread的scheduleLaunchActivity(…)方法,进入 ApplicationThread$scheduleLaunchActivity(…):public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, 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);
//用于封装启动Activity一些参数值
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;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);//发送消息
sendMessage(H.LAUNCH_ACTIVITY, r); }
发送消息,进入ActivityThead的handleLaunchActivity方法:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
......//注意点1:启动Activity
Activity a = performLaunchActivity(r, customIntent);if (a != null) {
r.createdConfig = new Configuration(mConfiguration); reportSizeConfigurations(r); Bundle oldState = r.state; // 注意点2: handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);......
}
上述代码标注了两个注意点,先看下注意点1的方法, 进入 performLaunchActivity方法:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {......
//获取要启动的Activity的ComponentName对象
ComponentName component = r.intent.getComponent(); if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); }.......
//创建Activity的上下文环境(ContentImpl继承自Context)
ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); //通过类加载器创建Activity对象 activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);.......
}
//获取Application对象
try { Application app = r.packageInfo.makeApplication(false, mInstrumentation);......
//初始化Activity类里的一些数据
activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback);if (customIntent != null) {
activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null; checkAndBlockForNetworkAccess(); activity.mStartedActivity = false; int theme = r.activityInfo.getThemeResource(); //Activity设置主题 if (theme != 0) { activity.setTheme(theme); }activity.mCalled = false;
//启动Activity if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()"); } r.activity = activity; r.stopped = true; //判断是否是结束Activity if (!r.activity.mFinished) { activity.performStart(); r.stopped = false; } if (!r.activity.mFinished) { if (r.isPersistable()) { if (r.state != null || r.persistentState != null) { mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState); } } else if (r.state != null) { //刚进来的Activity bundle数据为null//r.state 也就是我们保存的Bundle对象,要恢复的数据
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); } }......
}
在该方法里,比较重要的就是首先调用了Instrumentation的newActivity方法,进入到该方法,public Activity newActivity(Class<?> clazz, Context context,
IBinder token, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance) throws InstantiationException, IllegalAccessException { Activity activity = (Activity)clazz.newInstance(); ActivityThread aThread = null; activity.attach(context, aThread, this, token, 0 /* ident */, application, intent, info, title, parent, id, (Activity.NonConfigurationInstances)lastNonConfigurationInstance, new Configuration(), null /* referrer */, null /* voiceInteractor */, null /* window */, null /* activityConfigCallback */); return activity; }
通过反射创建了Activity。至此我们在注意下:在Instrumentation中创建Activity对象。
返回performLaunchActivity方法:创建Activity之后,设置主题,然后调用了Instrumentation的callActivityOnCreate方法,进入该方法:
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity); activity.performCreate(icicle); postPerformCreate(activity); }
调用了performCreate方法,进入Activity $ performCreate :
final void performCreate(Bundle icicle) { restoreHasCurrentPermissionRequest(icicle); // onCreate方法回调 onCreate(icicle); mActivityTransitionState.readState(icicle); performCreateCommon(); }(⊙﹏⊙),至此onCreate方法算是执行到了,那么onStart和onResume方法呢?继续探究。。。
再次回到 performLaunchActivity方法中, 调用了 performStart()方法,进入方法内:
final void performStart() {
..... mInstrumentation.callActivityOnStart(this); ..... }接下来还是通过调用了Instrumentation的callActivityOnStart()方法,内部再调用Activity的onStart()方法。
至此onStart方法调用了,那么 onResume呢? 继续深究。。。返回到handleLaunchActivity方法中,看下注意点2,进入到handleResumeActivity方法内:
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) { ...... r = performResumeActivity(token, clearHide, reason);.......
// Tell the activity manager we have resumed. if (reallyResume) { try { //Activity A 跳转到 Activity B ,当ActivityB创建并显示完毕之后,开始Activity A的onPauseme ActivityManager.getService().activityResumed(token); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } ......
进入到performResumeActivity方法:
public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide, String reason) { ...... r.activity.performResume(); ...... }
进入到Activity $ performResume:
final void performResume() { //是否是重新启动Activity performRestart();mFragments.execPendingActions();
mLastNonConfigurationInstances = null;
mCalled = false;
// mResumed is set by the instrumentation mInstrumentation.callActivityOnResume(this); ..... }
看见调用了Instrumentation的callActivityOnResume方法,还是通过Instrumentation间接调用Activity的回调方法。
public void callActivityOnResume(Activity activity) {
activity.mResumed = true; //调用了Activity的onResume方法: activity.onResume();if (mActivityMonitors != null) {
synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); am.match(activity, activity, activity.getIntent()); } } } }
至此开启APP从ActivityThread的main方法入口开始,Activity的启动流程就分析完了。
下一篇分析另一个切入点:Activity的startActivity方法以及Activity的销毁流程(finish)
Android进阶3:Activity源码分析(2) —— Activity启动和销毁流程(8.0)如果文章有错,感谢小伙伴指正,谢谢O(∩_∩)O。