对于一个从事Android开发或者学习Android开发的人而言,最初接触到的估计还是第一个应用程序“HelloWorld”,今天我们不讲helloworld。讲讲Activity。大家也许知道,Android在大体设计上其实也是遵循Web端的MVC设计的,Activity其实就是相当于我们的View+Controller(因为我们的Activity只要是展示界面,并且一般人的做法就是将数据的处理逻辑也放在Activity中)。大部分人都知道Activity的生命周期,可能觉得Activity的启动和创建都是从它的onCreate这里开始的。其实不然,说到底启动一个java编写的应用程序,我们大部分人的思维逻辑回事这样的,它的入口函数(main方法)在哪里?我也是网上查阅资料和视屏才有这样的想法的。其实当应用程序启动的时候,也是从main作为入口进入的,只不过大部分人没有找到这个main方法在哪里了,这就是我准备要说的第一个重要的类ActivityThread(它不是一个线程类,因为它不符合我们线程的实现方式)。在Android4.0的源码里面有这样一段对ActivityThread的简单说明:
This manages the execution of the mainthread in an application process, scheduling and executing activities, broadcasts,and other operations on it as the activitymanager requests.大概意思就是说,它在一个应用程序中管理者主线程的执行,例如activity,broadcast还有一些其他的操作。
先来看看ActivityThread中的main方法:
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");
}
}
函数首先初始化一个Looper对象,用于消息之间的通信,代码的16,17行初始化一个ActivityThread对象,调用thread.attach(false)方法,我们进入这个方法中查看:
private void attach(boolean system) {
sThreadLocal.set(this);
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
RuntimeInit.setApplicationObject(mAppThread.asBinder());
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
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);
}
}
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mPackages) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (applyConfigurationToResourcesLocked(newConfig, null)) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
public void onLowMemory() {
}
public void onTrimMemory(int level) {
}
});
}
代码12行初始化了一个ActivityManager对象,不过看名称就知道它是一个远程的ActivityManager对象,用来管理我们的Activity,
代码14行将我们的Applicatin对象与ActivityThread对象相关联。
代码23行初始化了一个在整个activity生命中期中处于比较重要地位的一个Instrumentation对象,它负责创建初始化Activity,Application等等,
24行初始化上下文ContextImpl(context是抽象类,只能初始化其实现类)
26行创建了Application对象(其实它的创建挺简单,就是利用反射机制,Class 对象,下文的Activity也是这样创建的,自己可以跟踪源代码查看)最后就是监听了系统的Configuration变化,并对不同的配置做出不同的消息响应。
了解完ActivityThread中的Main方法只会,我们就应该谈谈Activity的创建以及Activity的各个生命周期方法具体是怎么回调的呢?带着这些疑问继续来查看ActivityThread的源代码,发现有一个继承了Hanlder的类H ,它主要是进行系统之间的消息通信的,并联系着Activity各个生命周期函数。看看里面处理消息的handleMessage方法:
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;
case RELAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
} break;
case PAUSE_ACTIVITY:
handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
maybeSnapshot();
break;
case PAUSE_ACTIVITY_FINISHING:
handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
break;
case STOP_ACTIVITY_SHOW:
handleStopActivity((IBinder)msg.obj, true, msg.arg2);
break;
case STOP_ACTIVITY_HIDE:
handleStopActivity((IBinder)msg.obj, false, msg.arg2);
break;
case SHOW_WINDOW:
handleWindowVisibility((IBinder)msg.obj, true);
break;
case HIDE_WINDOW:
handleWindowVisibility((IBinder)msg.obj, false);
break;
case RESUME_ACTIVITY:
handleResumeActivity((IBinder)msg.obj, true,
msg.arg1 != 0);
break;
case SEND_RESULT:
handleSendResult((ResultData)msg.obj);
break;
case DESTROY_ACTIVITY:
handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
msg.arg2, false);
break;
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
break;
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looper.myLooper().quit();
break;
case NEW_INTENT:
handleNewIntent((NewIntentData)msg.obj);
break;
case RECEIVER:
handleReceiver((ReceiverData)msg.obj);
maybeSnapshot();
break;
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
case BIND_SERVICE:
handleBindService((BindServiceData)msg.obj);
break;
case UNBIND_SERVICE:
handleUnbindService((BindServiceData)msg.obj);
break;
case SERVICE_ARGS:
handleServiceArgs((ServiceArgsData)msg.obj);
break;
case STOP_SERVICE:
handleStopService((IBinder)msg.obj);
maybeSnapshot();
break;
case REQUEST_THUMBNAIL:
handleRequestThumbnail((IBinder)msg.obj);
break;
case CONFIGURATION_CHANGED:
handleConfigurationChanged((Configuration)msg.obj, null);
break;
case CLEAN_UP_CONTEXT:
ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
cci.context.performFinalCleanup(cci.who, cci.what);
break;
case GC_WHEN_IDLE:
scheduleGcIdler();
break;
case DUMP_SERVICE:
handleDumpService((DumpComponentInfo)msg.obj);
break;
case LOW_MEMORY:
handleLowMemory();
break;
case ACTIVITY_CONFIGURATION_CHANGED:
handleActivityConfigurationChanged((IBinder)msg.obj);
break;
case PROFILER_CONTROL:
handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
break;
case CREATE_BACKUP_AGENT:
handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
break;
case DESTROY_BACKUP_AGENT:
handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
break;
case SUICIDE:
Process.killProcess(Process.myPid());
break;
case REMOVE_PROVIDER:
completeRemoveProvider((IContentProvider)msg.obj);
break;
case ENABLE_JIT:
ensureJitEnabled();
break;
case DISPATCH_PACKAGE_BROADCAST:
handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
break;
case SCHEDULE_CRASH:
throw new RemoteServiceException((String)msg.obj);
case DUMP_HEAP:
handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
break;
case DUMP_ACTIVITY:
handleDumpActivity((DumpComponentInfo)msg.obj);
break;
case SLEEPING:
handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
break;
case SET_CORE_SETTINGS:
handleSetCoreSettings((Bundle) msg.obj);
break;
case UPDATE_PACKAGE_COMPATIBILITY_INFO:
handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
break;
case TRIM_MEMORY:
handleTrimMemory(msg.arg1);
break;
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what);
}
在handlerMessage方法中分别对了Activity不同生命周期做了相应的处理:在第9行中中handleLaunchActivity(r,null)处理了Activity创建执行的方法,我们跟踪进入这个方法
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
if (r.profileFd != null) {
mProfiler.setProfiler(r.profileFile, r.profileFd);
mProfiler.startProfiling();
mProfiler.autoStopProfiler = r.autoStopProfiler;
}
// Make sure we are running with the most recent config.
handleConfigurationChanged(null, null);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward);
if (!r.activity.mFinished && r.startsNotResumed) {
// The activity manager actually wants this one to start out
// paused, because it needs to be visible but isn't in the
// foreground. We accomplish this by going through the
// normal startup (because activities expect to go through
// onResume() the first time they run, before their window
// is displayed), and then pausing it. However, in this case
// we do -not- need to do the full pause cycle (of freezing
// and such) because the activity manager assumes it can just
// retain the current state it has.
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
// We need to keep around the original state, in case
// we need to be created again.
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);
} catch (RemoteException ex) {
// Ignore
}
}
}
会在代码的17行发现调用了ActivityThread的performLaunchActivity方法创建了一个Activity对象,而在代码的19-22行之中判断了如果Activity对象不为null,就去调用performResumeActivity方法,看见方法名就应该猜测得出是回调Activity的onResume方法,那么到底是不是这样呢?我们还是进入performLaunchActivity中看看他是如何执行的,下面是performLaunchActivity的具体代码实现:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (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 = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
ContextImpl appContext = new ContextImpl();
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
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;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
mInstrumentation.callActivityOnPostCreate(activity, r.state);
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
粗略的查看代码的22-31行就是利用java的反射机制创建我们具体的Activity对象,和前面所说的Application对象的创建类似,这个Activity就是我们函数需要返回的具体的Activity对象,至此时刻我么的Activity对象已近产生。
代码的52-73行就是初始化了上下文对象,并且调用了Activity的attach方法将Activiy与Application,Instrumentation,contextImpl关联起来,接下来就是我们最重要的第74行代码mInstrumentation.callActivityOnCreate(activity,r.state),跟踪进入,探探究竟
ublic void callActivityOnCreate(Activity activity, Bundle icicle) {
if (mWaitingActivities != null) {
synchronized (mSync) {
final int N = mWaitingActivities.size();
for (int i=0; i<N; i++) {
final ActivityWaiter aw = mWaitingActivities.get(i);
final Intent intent = aw.intent;
if (intent.filterEquals(activity.getIntent())) {
aw.activity = activity;
mMessageQueue.addIdleHandler(new ActivityGoing(aw));
}
}
}
}
activity.performCreate(icicle);
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());
}
}
}
}
只需要看代码第
16
行调用了
Activity
本身的
performCreate(icicle)
,并传入了
Bundle
对象,再跟进
performCreate
方法中,
final void performCreate(Bundle icicle) {
onCreate(icicle);
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
}
哈哈哈 ,至此终于看到了我们的Activity的onCreate(icicle)的回调方法了吧,到这里我们也将Activity的onCreate究竟怎么调用的顺序流程走了一遍,如果想要看Activity的其他生命周期方法的回调,也可以按照这样一条路线走下去,这里就不在赘述了。
直到现在写这篇文章的目的,就是由于以前一直想写文章可是根本就没有坚持,以至于好多东西看过又忘记了,后来再去看,得重新整理思路,现在开始写文章,就是将自己的理解思路记录下来,以后回顾查看的时候不至于走很多弯路。文章如有什么不好的地方,请大家多多指正,一起共同进步,谢谢。