关于Activity的源码分析,看了足足有半个月,理由就是:
1:Activity源代码很多,逻辑很复杂
2:下班再能加班学习,礼拜天抽空学习源码
至于为什么看源码:因为偶尔看到一句话:不懂Activity的onCreate的内部源码,你敢说你是Android开发程序猿?!
其实关于这篇文章,我想了很久,不太敢贸然写,因为牵涉的类有点多并且复杂,怕理解出错,给各位小伙伴带来困扰,经过学习了两个礼拜,学到了一点东西,总结一下。
首先Activity的启动切入点有两个,startActivity切入和ActivityThread的main方法切入,最终的效果都是开启一个新的Activity。 本篇文章先从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("" );
//注意点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方法,看下三个注意点:
进入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("" ,
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 IActivityManagerSingleton =
new Singleton() {
@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 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);
}
......
}
看下注意点:
首先说下注意点看,进入到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 pendingResults, List 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; ifinal 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。