工厂模式比较好理解。uml图如下:
接下来主要要讲的是onCreate方法
一个Activity的onCreate方法相当于一个工厂方法,那么这个onCreate方法是怎么启动的呢?
对于一个应用程序来说,它的真正入口是ActivityThread的main方法。
ActivityThread.java
package android.app;
public final class ActivityThread {
public static void main(String[] args) {
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);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
private void attach(boolean system) {
sThreadLocal.set(this);
mSystemThread = system;
if (!system) {
// 非System部分的代码
...
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {
// System部分的代码
android.ddm.DdmHandleAppName.setAppName("system_process");
try {
mInstrumentation = new Instrumentation();
ContextImpl context = new ContextImpl();
context.init(getSystemContext().mPackageInfo, null, this);
Application app = Instrumentation.newApplication(Application.class, context);
mAllApplications.add(app);
mInitialApplication = app;
app.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
...
}
最核心的是mgr.attachApplication(mAppThread);这行代码。
这里的非System部分,ActivityManagerNative.getDefault()返回的是一个ActivityMAnagerService(AMS)对象,主要是调用AMS的attachApplication方法,将ApplicationThread绑定至AMS中。看看AMS的attachApplication方法做了什么。
com/android/server/am/ActivityManagerService.java
public ActivityStack mMainStack;
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
//调用此方法进行的绑定
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
thread.bindApplication方法是将ApplicationThread对象绑定到ActivityManagerService.
然后真正启动Acticity的方法是mMainStack.realStartActivityLocked(hr, app, true, true)
ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
try {
thread.bindApplication(processName, appInfo, providers,
app.instrumentationClass, profileFile, profileFd, profileAutoStop,
app.instrumentationArguments, app.instrumentationWatcher, testMode,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
} catch (Exception e) {
return false;
}
ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
if (hr != null && normalMode) {
if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (Exception e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
badApp = true;
}
} else {
mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
}
}
}
thread.bindApplication有什么作用?留以后再看。
我们来看ActivityStack具体的realStartActivityLocked方法。
ActivityStack.java
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
//冻结尚未启动的其他Activity
r.startFreezingScreenLocked(app, 0);
//向WindowManager设置Token,标识当前App位于前台显示,
mService.mWindowManager.setAppVisibility(r.appToken, true);
// 搜集启动较慢的App信息
r.startLaunchTickingLocked();
// 检查配置信息
if (checkConfig) {
Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken : null);
mService.updateConfigurationLocked(config, r, false, false);
}
//设置参数
r.app = app;
app.waitingToKill = null;
...
try {
//将桌面的Acticity添加到当前Activity栈到底部
if (r.isHomeActivity) {
mService.mHomeProcess = app;
}
mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
...
//所有参数信息到位后准备启动Acticity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
new Configuration(mService.mConfiguration),
r.compat, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
...
return true;
}
该方法中,首先会设置相关参数信息,然后调用app.thread.scheduleLaunchActivity方法来启动Activity。也就是ActivityThread类的一个内部类ApplicationThread的scheduleLaunchActivity方法来启动Activity。也就是ActivityThread类的一个内部类ApplicationThread方法。
ActivityThread.java
private class ApplicationThread extends ApplicationThreadNative {
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
...
updatePendingConfiguration(curConfig);
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
}
scheduleLaunchActivity构造了一个ActivityClientRecord对象,设置相关参数,最后通过sendMassage方法发送启动消息到消息队列,由ActivityThread的Handler处理启动,即ActivityThread内部的一个继承自Handler的字类H。
ActivityThread.java
public final class ActivityThread {
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
switch (msg.what) {
case LAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
} break;
...
}
}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity a = performLaunchActivity(r, customIntent);
...
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
f (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//构造Activity对象并设置参数
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
} catch (Exception e) {
}
try {
//获取Application对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
ContextImpl appContext = new ContextImpl();
//将Application对象,Context对象绑定到Activity对象
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
//调用Activity的onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state);
} catch (Exception e) {
}
return activity;
}
Instrumentation类会在应用的任何代码执行前被实列化,用来监控系统与应用的交互。可以看到Activity在这里调用了performCreate方法,并最终在performCreate方法里执行了onCreate方法。
Instrumentation.java
public class Instrumentation {
public void callActivityOnCreate(Activity activity, Bundle icicle) {
...
activity.performCreate(icicle);
...
}
Activity.java
final void performCreate(Bundle icicle) {
onCreate(icicle);
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
}
接下来主要要讲的是onCreate方法
一个Activity的onCreate方法相当于一个工厂方法,那么这个onCreate方法是怎么启动的呢?
对于一个应用程序来说,它的真正入口是ActivityThread的main方法。
ActivityThread.java
package android.app;
public final class ActivityThread {
public static void main(String[] args) {
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);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
private void attach(boolean system) {
sThreadLocal.set(this);
mSystemThread = system;
if (!system) {
// 非System部分的代码
...
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {
// System部分的代码
android.ddm.DdmHandleAppName.setAppName("system_process");
try {
mInstrumentation = new Instrumentation();
ContextImpl context = new ContextImpl();
context.init(getSystemContext().mPackageInfo, null, this);
Application app = Instrumentation.newApplication(Application.class, context);
mAllApplications.add(app);
mInitialApplication = app;
app.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
...
}
最核心的是mgr.attachApplication(mAppThread);这行代码。
这里的非System部分,ActivityManagerNative.getDefault()返回的是一个ActivityMAnagerService(AMS)对象,主要是调用AMS的attachApplication方法,将ApplicationThread绑定至AMS中。看看AMS的attachApplication方法做了什么。
com/android/server/am/ActivityManagerService.java
public ActivityStack mMainStack;
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
//调用此方法进行的绑定
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
thread.bindApplication方法是将ApplicationThread对象绑定到ActivityManagerService.
然后真正启动Acticity的方法是mMainStack.realStartActivityLocked(hr, app, true, true)
ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
try {
thread.bindApplication(processName, appInfo, providers,
app.instrumentationClass, profileFile, profileFd, profileAutoStop,
app.instrumentationArguments, app.instrumentationWatcher, testMode,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
} catch (Exception e) {
return false;
}
ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
if (hr != null && normalMode) {
if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (Exception e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
badApp = true;
}
} else {
mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
}
}
}
thread.bindApplication有什么作用?留以后再看。
我们来看ActivityStack具体的realStartActivityLocked方法。
ActivityStack.java
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
//冻结尚未启动的其他Activity
r.startFreezingScreenLocked(app, 0);
//向WindowManager设置Token,标识当前App位于前台显示,
mService.mWindowManager.setAppVisibility(r.appToken, true);
// 搜集启动较慢的App信息
r.startLaunchTickingLocked();
// 检查配置信息
if (checkConfig) {
Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken : null);
mService.updateConfigurationLocked(config, r, false, false);
}
//设置参数
r.app = app;
app.waitingToKill = null;
...
try {
//将桌面的Acticity添加到当前Activity栈到底部
if (r.isHomeActivity) {
mService.mHomeProcess = app;
}
mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
...
//所有参数信息到位后准备启动Acticity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
new Configuration(mService.mConfiguration),
r.compat, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
...
return true;
}
该方法中,首先会设置相关参数信息,然后调用app.thread.scheduleLaunchActivity方法来启动Activity。也就是ActivityThread类的一个内部类ApplicationThread的scheduleLaunchActivity方法来启动Activity。也就是ActivityThread类的一个内部类ApplicationThread方法。
ActivityThread.java
private class ApplicationThread extends ApplicationThreadNative {
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
...
updatePendingConfiguration(curConfig);
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
}
scheduleLaunchActivity构造了一个ActivityClientRecord对象,设置相关参数,最后通过sendMassage方法发送启动消息到消息队列,由ActivityThread的Handler处理启动,即ActivityThread内部的一个继承自Handler的字类H。
ActivityThread.java
public final class ActivityThread {
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
switch (msg.what) {
case LAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
} break;
...
}
}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity a = performLaunchActivity(r, customIntent);
...
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
f (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//构造Activity对象并设置参数
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
} catch (Exception e) {
}
try {
//获取Application对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
ContextImpl appContext = new ContextImpl();
//将Application对象,Context对象绑定到Activity对象
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
//调用Activity的onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state);
} catch (Exception e) {
}
return activity;
}
Instrumentation类会在应用的任何代码执行前被实列化,用来监控系统与应用的交互。可以看到Activity在这里调用了performCreate方法,并最终在performCreate方法里执行了onCreate方法。
Instrumentation.java
public class Instrumentation {
public void callActivityOnCreate(Activity activity, Bundle icicle) {
...
activity.performCreate(icicle);
...
}
Activity.java
final void performCreate(Bundle icicle) {
onCreate(icicle);
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
}