前言
关于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() {
@Override
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>() {
@Override
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(…):
@Override
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。
Android学习交流群: