四大组件的运行状态:
Android中的四大组件中除了BroadcastReceiver以外,其他三种组件都必须在Android Mainfrst中注册。对于,BroadcastReceiver来说,他既可以在AndroidMainfrst中注册也可以通过代码来注册。在调用方式上,Activity,Service和BroadcastReceiver需要借助Intent,而ContentProvider则无需借助Intent。
Activity的工作过程:
为了方便日常的开发工作,系统对四大组件的工作过程进行了很大程度的封装,这使得开发者无需关注实现细节即可快速的使用四大组件。Activity作为很重要的一个组件,其内部工作过程系统当然也是做了很多的封装,这种封装使得启动一个Activity变得异常的简单。在显示调用的情形下,只需要通过如下代码即可完成:
Intent intent=new Intent(this,TestActivity.class);
startActivity(intent);
通过上面的代码即可启动一个具体的activity,然后新Activity就会被系统启动并展示在 用户的眼前,这个过程对于Android开发者来说最普通不过了,这也是很理所当然的事情,但是有没有想过系统内部到底是如何启动一个Activity的呢?下面我们就来介绍一下。
注意一点:在研究内部实现上应该更加侧重于对整体流程的把握,而不能深入代码细节不能自拔,太深入代码细节往往会导致越看越迷茫的撞到。无法对整体流程建立足够的认识,取而代之的是繁琐的细节。但是代码的细节本身不具有太多的指导意义,因此这种学习状态是要极力避免的。所以本博客会侧重于对Activity工作过程的分析整体流程。
我们从Acitivity的startActivity的方法开始分析,startActivity的方法有好几种重载方式,但是他们最终都会调用startActivityForResult方法,实现如下:
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
在上面的代码中,我们只需要关注mParent==null这部分逻辑,mParent代表的是ActivityGroup,ActivityGroup最开始被用来在一个界面中嵌入多个子Activity,但是其在API13中已经被废弃了,系统推荐采用Fragment来代替ActivityGroup,Fragment的好处就不多说了、在上面的代码中需要注意mMainThread.getApplicationThread()这个参数,他的类型是ApplicationThread,ApplicationThread是ActivityThread在Activity的启动过程中发挥着很重要的作用。接着看一下Instrumentation的execStartActiivty方法。如下所示:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
从上面的代码来看,启动Actiivty真正的实现由ActivityManagerNative.getDefault()的startActivity方法完成。ActivityManagerService(简称AMS)继承自Binder并实现了IActivityManager这个Binder接口,因此AMS也是一个Binder,他是IActivityManager的具体实现。由于ActivityManagerNative.getDefault()其实是一个IActivityManager类型的Binder对象,因此他的具体实现是AMS。可以发现,在ActivityManagerNative中。AMS这个Binder对象采用单例模式对外提供,Singleton是一个单利的封装类,第一次调用它的get方法时他会通过create方法来初始化AMS这个Binder对象,在后续的调用中则直接返回之前创建的对象,源码如下:
static public IActivityManager More ...getDefault() {
return gDefault.get();
}
private static final Singleton
protected IActivityManager More ...create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
再附上ActivityManagerNative的完整源码地址:[源码](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/app/ActivityManagerNative.java),有兴趣的可以去阅读一下。
从上面的分析可以知道,Activity由ActivityManagerNative.getDefault()来启动。而ActivityManagerNative.getDefault()实际上是AMS,因此Activity的启动过程又转移到了AMS中,为了继续分析这个过程,只需要查看AMS的startActivity方法即可,在分析AMS的startActivity方法之前,我们先回过头来看一下Instrumentation的execStartActivity方法,其中有一行代码:checkStartActivityResult(result,intent),直观上看起来这个方法的作用像是在检查启动Activity的记过,他的具体实现如下所示:
/package/ static void checkStartActivityResult(int res, Object intent) {
if (res >= ActivityManager.START_SUCCESS) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
throw new AndroidRuntimeException(
"FORWARD_RESULT_FLAG used while also requesting a result");
case ActivityManager.START_NOT_ACTIVITY:
throw new IllegalArgumentException(
"PendingIntent is not an activity");
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}
从上面的代码可以看出,checkStartActivityResult的作用很明显,就是检查启动Activity的结果,当无法正确启动一个Activity时,这个方法会抛出异常信息,其中最熟悉不过的就是"unable to find expliit activity class; have you declared this activity in your androidmainfest.xml"这个异常我就不说了,你懂的。
接着我们继续分析AMS的startActivity方法,如下所示:
public final int More ...startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode,
startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
}
public final int More ...startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "startActivity", null);
return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
null, null, options, userId);
}
可以看出,Activity的启动过程又转移到了ActivityStackSupervisor的startActivityMayWait方法中了。在startActivityMayWait中又调用了startActivityLocked方法,接着startActivityLocked又调用了ActivityStack的resumeTopActivityiesLocked方法,这个时候启动过程已经从ActivityStackSupervisor转移到了ActivityStack。
ActivityStack的resumeTopActivitiesLocked方法的实现如下所示:
final boolean More ...resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
inResumeTopActivity = false;
}
return result;
}
从上面的代码可以看出,resumeTopActivityLocked调用了resumeTopActivityInnerLocked方法,resumeTopActivityInnerLocked方法又调用了ActivityStackSupervisor的satrtSpecificActivityLocked方法,satrtSpecificActivityLocked的源码如下:
void More ...startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
从上面的代码可以看出,satrtSpecificActivityLocked方法调用了realStartActivityLocked方法,为了更清晰的说明Activity的启动过程在ActivityStatckSupervisor和ActivityStack之间的传递顺序,下面给出一张流程图。
![image.png](https://upload-images.jianshu.io/upload_images/5272505-5da279e97763d4df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在ActivityStackSupervisor的realStartActivityLocked方法中 又如下 一段代码:
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
results, newIntents, !andResume, mService.isNextTransitionForward(),
profilerInfo);
这段代码很重要,其中app.thread的类型为IApplicationThread,IApplicationThread的声明如下:
[查看源码](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.0_r1/android/app/IApplicationThread.java#IApplicationThread)
因为他继承了IInterface接口,所以他是一个Binder类型的接口,从IApplicationThread声明的接口方法中可以看出,其内部包含了大量启动,停止Activity 的接口,此外还包含了启动和停止服务的接口,从接口的方法的命名可以猜测,IApplicationThread这个Binder接口的实现者完成了大量和Activity以及Service启动停止相关的功能。
那么IApplicationThread的实现者到底是什么?答案就是ActivityThread中的内部类ApplicationThread,洗面来看ApplicationThread的定义:
private class More ...ApplicationThread extends ApplicationThreadNative
public abstract class More ...ApplicationThreadNative extends Binder
implements IApplicationThread
可以看出,ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative则继承了Binder并实现了IApplicationThread接口。如果读者还记得系统的AIDL文件自动生成的代码,就会发现ApplicationThreadNative的作用其实和系统为AIDL文件生成的类是一样的。
在ApplicationThreadNative的内部,还有一个ApplicationThreadProxy类,这个类的实现如下所示,其实这个内部类也是系统为AIDL文件自动生成的代理类。所以ApplicationThreadNative就是IApplicationThread的实现者,由于ApplicationThreadNative被系统定义为抽象类,所以ApplicationThread就成了IApplicationThread的最终实现者了。
class More ...ApplicationThreadProxy implements IApplicationThread {
private final IBinder mRemote;
public More ...ApplicationThreadProxy(IBinder remote) {
mRemote = remote;
}
public final IBinder More ...asBinder() {
return mRemote;
}
public final void More ...schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished ? 1 : 0);
data.writeInt(userLeaving ? 1 :0);
data.writeInt(configChanges);
data.writeInt(dontReport ? 1 : 0);
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
public final void More ...scheduleStopActivity(IBinder token, boolean showWindow,
int configChanges) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(showWindow ? 1 : 0);
data.writeInt(configChanges);
mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
...
}
绕了一大圈,Activity的启动过程最终回到了ApplicationThread中,ApplicationThread通过scheduleLaunchActivity方法来启动Activity,代码如下:
public final void More ...scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List
List
ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
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;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
接下来看一下Handler H对消息的处理,如下所示:
private class More ...H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
public static final int PAUSE_ACTIVITY_FINISHING= 102;
public static final int STOP_ACTIVITY_SHOW = 103;
public static final int STOP_ACTIVITY_HIDE = 104;
public static final int SHOW_WINDOW = 105;
public static final int HIDE_WINDOW = 106;
public static final int RESUME_ACTIVITY = 107;
public void More ...handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case PAUSE_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
(msg.arg1&2) != 0);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
....
}
从Handler H对“LAUNCH_ACTIVITY”这个消息的处理可以知道,Activity的启动过程 由ActivityThread的handleLaunchActivity方法实现,他的源码如下:
private void handleLaunceActivity(ActivityClientRecord r,Iintent customIntent){
...
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.statr;
handleResumeActivity(r.token,false,r.isForward,!r.activity.mFinished&&!r. startsNotResumed);
...
}
...
}
从上面的源码可以看出,perforLaunchActivity方法最终完成了Activity对象的创建和启动过程,并且ActivityThread通过handleResumeActivity方法来调用被启动Activity的onResume这以生命周期方法。
perforLaunchActivity这个方法主要完成了如下几件事情:
## 1.从ActivityClientRecord中获取待启动的Activity的组件信息。
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);
}
2.通过Instrumentation的newActivity方法使用类加载器创建Activity对象:
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);
r.intent.prepareToEnterProcess();
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);
}
}
至于Instrumentation的newActivity,他的实现比较简单,就是通过类加载器来创建Activity对象:
public Activity More ...newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
3,通过LoadedApk的makeApplication方法来尝试创建Application对象:
public Application More ...makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
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")) {
initializeJavaContextClassLoader();
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
从makeApplication的实现可以看出,如果Application已经被创建过了,那么就不会再重复创建了,这也意味着一个应用只有一个Application对象,Application对象的创建也是通过Instrumentation来完成,这个过程和Activity的创建一样,都是通过类加载器来实现的,Application创建完毕后,系统会通过Instrumentation的callApplicationOnCreate来调用Application的onCreate方法。
## 4.创建ContextImpl对象并通过Activity的attach方法来完成一些重要的数据初始化:
ContextImpl是一个很重要的数据结构,他是Context的具体实现,Context中的大部分逻辑都是由ContextImpl来完成的。ContxetImpl是通过Activity的attach的方法和Activity建立关联的,除此之外,在attach方法中Activity还会完成Window的创建并建立自己和Window的关联,这样当Window接受到外部输入事件后,就可以将事件传递给Acivity
## 5.调用Activity的onCreate方法
mInstrumentation。callActivityOnCreate(activity,r.state),由于Activity的onCreate已经被调用,这也意味着Activity已经完成了整个启动过程。