您的位置:首页 > 移动开发 > Android开发

Android Activity启动过程全解析

2015-11-25 10:15 459 查看
首先参考:

【凯子哥带你学Framework】Activity启动过程全解析

关键概念

zygote进程

这里面讲的很详细,先摘抄其中重要的部分出来,方便以后记忆

每一个App其实都是

一个单独的dalvik虚拟机

一个单独的进程

Android是基于Linux System的,当你的手机开机的时候,Linux的内核加载完成之后就会启动一个叫“init“的进程。zygote进程是由init进程fork出来的,当系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进程的方式,是通过fork第一个zygote进程实现的.

Android Framework里面两大非常重要的进程之一

1. zygote进程

2. SystemServer也是一个进程,而且是由zygote进程fork出来的,这个主要开启重要的系统服务,比如ActivityManagerService、PackageManagerService、WindowManagerService

AMS

ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。

ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService

在创建AMS之前会调用createSystemContext()创建系统上下文的时候,也已经完成了mSystemContext和ActivityThread的创建。然后创建AMS,在然后,会开启系统的Launcher程序,完成系统界面的加载与显示。

如果想打开一个App的话,需要AMS去通知zygote进程,来fork一个新进程,来开启我们的目标App的。除此之外,其实所有的Activity的开启、暂停、关闭都需要AMS来控制,所以我们说,AMS负责系统中所有Activity的生命周期。

我们的App和AMS(SystemServer进程)还有zygote进程分属于三个独立的进程,他们之间如何通信呢?

App与AMS通过Binder机制进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。

Launcher

当我们点击手机桌面上的图标的时候,App就由Launcher开始启动了。Launcher本质上也是一个应用程序,和我们的App一样。

Launcher中点击图标,Launcher会判断哪个图标对应哪个应用程序,封装intent,然后使用这个intent开启一个App,其实和我们在Activity中直接startActivity()基本一样,都是调用了Activity.startActivityForResult()。

Instrumentation

每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。当startActivityForResult()调用之后,实际上还是调用了mInstrumentation.execStartActivity()

public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...ignore some code...
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, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}


先提一下,当AMS通知ActivityThread启动一个activity的时候,首先会执行handleLaunchActivity方法,这个方法里面会去回调activity的各个生命周期函数。具体handleLaunchActivity方法在什么时候被调用后面分析

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
..........
Activity a = performLaunchActivity(r, customIntent);

if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
}
........


performLaunchActivity方法创建activity,内部其实都是调用Instrumentation的相关方法,然后在调用activity的onCreat和onStart等生命周期方法

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//说明如果一个activity有构造函数,那么这个构造函数是优先于onCreate方法执行的
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
}

try {
//把之前创建的application对象取出来
Application app = r.packageInfo.makeApplication(false, mInstrumentation);

if (activity != null) {
//绑定ContextImpl对象给该Activity
Context appContext = createBaseContextForActivity(r, activity);
//做attach,attah里面会赋值mWindow,mApplication,mWindowManager等
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.voiceInteractor);

activity.mCalled = false;
if (r.isPersistable()) {
//最终会调用到Activity的onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}

if (!r.activity.mFinished) {
//实际调用mInstrumentation.callActivityOnStart(this);,然后调用Activity的onStart方法
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
//调用Activity的onRestoreInstanceState方法
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
////调用Activity的onPostCreate方法
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
}
}
}
return activity;
}


这里举个例子,执行了mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);怎么就回调了activity的onCreate方法

//Instrumentation方法
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
//Activity方法
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
onCreate(icicle, persistentState);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}


performLaunchActivity执行完后执行handleResumeActivity-performResumeActivity方法,有r.activity.performResume();

final void performResume() {
............
mInstrumentation.callActivityOnResume(this);
............
}


然后就回调了activity的onResume方法

这里稍微总结一下:

第一步,执行activity有构造函数,那么这个构造函数是优先于onCreate方法执行的

第二步,performLaunchActivity中把一个ContextImpl对象给该Activity的父类ContextWrapper的mBase属性,这里的分析见《Android Context详解》

第二步,performLaunchActivity中调用attach方法,赋值mWindow,mApplication,mWindowManager等。mWindow,mWindowManager有啥用?见《Android 窗口添加机制系列1-Activity》

第二步,performLaunchActivity中然后回调activity的onCreate,onStart,onRestoreInstanceState,onPostCreate方法

第三步,第二部创建完初始化完acitivity调用handleResumeActivity回调activity的onResume方法,在窗口机制里面,也说过这里会把顶层的DecorView添加到window-WMS中去

Activity启动流程

前面说过startActivity实际上调用的是Instrumentation的execStartActivity方法

public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Fragment 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<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 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.mWho : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}

public abstract class ActivityManagerNative extends Binder implements IActivityManager{
//从类声明上,我们可以看到ActivityManagerNative是Binder的一个子类,而且实现了IActivityManager接口
static public IActivityManager getDefault() {
return gDefault.get();
}

//通过单例模式获取一个IActivityManager对象,这个对象通过asInterface(b)获得
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager 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;
}
};
}

//最终返回的还是一个ActivityManagerProxy对象
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}

//这里面的Binder类型的obj参数会作为ActivityManagerProxy的成员变量保存为mRemote成员变量,负责进行IPC通信
return new ActivityManagerProxy(obj);
}

}


ActivityManagerProxy.startActivity(),在这里面做的事情就是IPC通信,利用Binder对象,调用transact(),把所有需要的参数封装成Parcel对象,向AMS发送数据进行通信。

看这里IBinder b = ServiceManager.getService(“activity”);之前有介绍过获取PhoneInterfaceManager的时候是这样的ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); 这个类似,所以其实这里的IBinder拿到的其实就是AMS(ActivityManagerService)

public static final String ACTIVITY_SERVICE = "activity";
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
}
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
........
data.writeInt(requestCode);
data.writeInt(startFlags);
........
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
........
return result;
}


客户端:ActivityManagerProxy =====>Binder驱动=====> ActivityManagerService:服务器

流程现在进入了AMS,告诉AMS我要启动一个activity了,接下来AMS中的流程就不贴了,也没啥必要,看参考链接的吧。

【凯子哥带你学Framework】Activity启动过程全解析

//省略AMS中的代码流程


ActivityStack的resumeTopActivityInnerLocked方法中

// We need to start pausing the current activity so the top one
// can be resumed...
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
}


说明在启动activity前,栈顶的activity需要先onpause,新的activity才能启动,所以不能在onpause中做耗时的操作,否则会造成新的activity启动的很慢,此时可以把耗时操作放在Onstop中处理

然后AMS通过以下方式来通知ActivityThread

客户端:ApplicationThread <=====Binder驱动<===== ApplicationThreadProxy:服务器

来一张高清无码大图,方便大家记忆:



如果应用进程还没打开,那么首先会开启main线程,当然就是执行ActivityThread的main方法

public static void main(String[] args) {

Looper.prepareMainLooper();

ActivityThread thread = new ActivityThread();
thread.attach(false);

if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}

AsyncTask.init();

if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}

Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");
}
}


这里做了两件事情

开启主线程的消息循环

做主线程的attach

attach方法里执行mgr.attachApplication(mAppThread),然后通过Binder调用到AMS里面对应的attachApplication方法

AMS方法attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
...........
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
...........
mStackSupervisor.attachApplicationLocked(app);
...........


首先thread.bindApplication中

thread是IApplicationThread,实际上就是ApplicationThread在服务端的代理类ApplicationThreadProxy,然后又通过IPC就会调用到ApplicationThread的对应方法

先调用ApplicationThreadProxy的bindApplication方法,然后通过IBinder调用的是ApplicationThread的bindApplication方法中会sendMessage(),里面有函数的编号H.BIND_APPLICATION,然后这个Messge会被H这个Handler处理

private class H extends Handler {

...ignore some code...

public static final int BIND_APPLICATION        = 110;

...ignore some code...

public void handleMessage(Message msg) {
switch (msg.what) {
...ignore some code...
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...ignore some code...
}
}


ApplicationThread是ActivityThread的内部类

上面的代码也充分说明了AMS通过以下方式来通知ActivityThread

客户端:ApplicationThread <=====Binder驱动<===== ApplicationThreadProxy:服务器

看到了吗? 重要执行到了handleBindApplication,这个方法是不是很熟悉?之前在《Android Context详解》这篇文章就说到,创建单例的Application对像就是从这个方法开始滴。

然后执行完thread.bindApplication也就是说此时完成了Application相关的初始化,然后执行mStackSupervisor.attachApplicationLocked(app);然后会调用realStartActivityLocked方法。

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);


跟上面的是不是很像,先调用ApplicationThreadProxy的scheduleLaunchActivity方法,然后通过IBinder调用的是ApplicationThread的scheduleLaunchActivity方法。scheduleLaunchActivity方法中

同上发送一个标识为H.LAUNCH_ACTIVITY的消息

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);


最后看到了吗?执行了handleLaunchActivity方法,这个方法很熟悉吧?执行Activity生命周期就是从这个方法开始的,见《Instrumentation》章节

现在整个流程终于清晰了吧?

另一方面,如果是启动同一个应用的activity,那么就不会有bindApplication的流程啦,就不会再重复初始化application,只会初始化该activity
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android