> 文档中心 > Android应用程序启动流程之从startActivity开始

Android应用程序启动流程之从startActivity开始


1.简介:

Android系统中,应用程序是由框架创建的。通过startAcitivty函数可以启动一个应用程序,那么,startActivity到底做了些什么,以至于这样一个简单的几行代码就能调用起一个应用程序。本节分析startActivity的执行流程。

2.从Activity的startActivity开始:

当调用startActivity函数时,通过Android Binder机制, 调用到ActivityManagerService.再由ActivityManagerService去创建Java层的Process。
并且最终通过Zygote的fork去真正的创建出一个进程,当然,这个进程可以在adb终端使用ps命令列出来。

当点击一个桌面app图标时,会调用startActivityForResult,然后,会调用到Instrumentation.execStartActivity,并且最终调用到ActivityMangerService的startActivity中,整个流程如下:

 2.1 startActiivy时序图如下:

这样,代码就进入到ActivityManagerService中了,如下图:

可见,ActivityStack对activity进行了管理。

在1.9startSpecificActivityLocked中,会判断app创建没有,如果创建了,就调用

realStartActivityLocked,

否则,就会调用startProcessLocked。

2.2 分支一:realStartActivityLocked函数分析:

最关键的就是:

app.thread.scheduleLaunchActivity

方法的调用。这个app.thread类型是

IApplicationThread

所以,这里通过Binder调用到了ApplicationThreadNative的scheduleLaunchActivity,然后,又调用到了ActivityThread的“scheduleLaunchActivity”。

ActivityThread的scheduleLaunchActivity方法:

queueOrSendMessage(H.LAUNCH_ACTIVITY, r);   ->    mH.sendMessage(msg);->H.handleMessage()中,有:case LAUNCH_ACTIVITY: {     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");     ActivityClientRecord r = (ActivityClientRecord)msg.obj;     r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);     handleLaunchActivity(r, null);     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}

handleLaunchActivity方法调用了

performLaunchActivity

,在这个方法中,创建了Activity(终于,Activity创建):

//performLaunchActivity方法的实现: 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);     } }  ...... Application app = r.packageInfo.makeApplication    ...... activity.attach ...... mInstrumentation.callActivityOnCreate(activity, r.state);

这样,通过mInstrumentation 创建了Activity,并且执行attach后,再执行

callActivityOnCreate

就进入到Activity的OnCreate生命周期了。

2.3 分支二:startProcessLocked的执行

在执行到startProcessLocked时,代码由ActivityStack进入到ActivityManagerService中,继续执行,如下图:

在Process.java中,有

     argsForZygote.add("--runtime-init");     argsForZygote.add("--setuid=" + uid);     argsForZygote.add("--setgid=" + gid);     ......  zygoteSendArgsAndGetResult(argsForZygote)

 openZygoteSocketIfNeeded函数的实现:

try {  sZygoteSocket = new LocalSocket();  sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,    LocalSocketAddress.Namespace.RESERVED));  sZygoteInputStream   = new DataInputStream(sZygoteSocket.getInputStream());  sZygoteWriter =      new BufferedWriter(new OutputStreamWriter( sZygoteSocket.getOutputStream()),256);  Log.i("Zygote", "Process: zygote socket opened");  sPreviousZygoteOpenFailed = false;  break;     } catch (IOException ex) {  ......     }

分析:

创建一个LocalSocket sZygoteSocket,作为client通过调用sZygoteSocket.connect 去连接socket,而作为服务端的socket,就是在Zygote初始化时在runSelectLoop中进行监听的套接字,然后,在Zygote中去真正地用fork创建进程。

参见:

Android系统的心脏-Zygote进程如何fork一个新的应用进程

 这样,进程就创建好了。

进程创建好之后,代码回到Process.java中,继续执行。保存进程状态,然后,去创建ActivityThread。(在Process.start时,就将ActivityThread这个类名传递过来了)。

3. ActivityThread:

我们继续分析Application的创建过程(即“分支二:startProcessLocked的执行”的继续执行)

在ActivityThread的main函数中,主要功能:

1)创建Thread;并调用attach方法;

2)进行Application的attach;

3)进行Handler的创建和message的处理;

4)AsyncTask的初始化。

3.1 ActivityThread中的main函数

直接看ActivityThread中的main函数:

public static void main(String[] args) { ...... Looper.prepareMainLooper(); if (sMainThreadHandler == null) {     sMainThreadHandler = new Handler(); } ActivityThread thread = new ActivityThread(); thread.attach(false); AsyncTask.init(); if (false) {     Looper.myLooper().setMessageLogging(new      LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited");    }

 thread.attach()的实现:

IActivityManager mgr = ActivityManagerNative.getDefault();    mgr.attachApplication(mAppThread);

3.2 attachApplication方法的执行序列(通过Binder机制实现):

1) 从Client端到Server端:

注意,这里的mgr是ActiivtyManagerProxy的实例,而ActiivtyManagerProxy是Binder机制中的Client端,是服务端AMS(ActivityManagerService)的代理。

再通过Binder IPC机制调用到AMS的对应的方法中,调用序列如下:

1. client端:

ActivityManagerNative.getDefault://获取ActivityManagerProxy

ActivityManagerProxy.attachApplication -> mRemote.transact, 如下:

    public void attachApplication(IApplicationThread app) throws RemoteException    { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder()); mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle();    }

这样,通过Binder机制就执行到了ActivityManagerService中了。

2. server端:

在ActivityManagerNative中,有对ATTACH_APPLICATION_TRANSACTION的处理(这时,已经是在Service执行这个case了):

case ATTACH_APPLICATION_TRANSACTION: {     data.enforceInterface(IActivityManager.descriptor);     IApplicationThread app = ApplicationThreadNative.asInterface(      data.readStrongBinder());     if (app != null) {  attachApplication(app);     }     reply.writeNoException();     return true; }

而这里的attachApplication方法就在ActivityManagerService中有实现,代码如下:

    public final void attachApplication(IApplicationThread thread) { synchronized (this) {     int callingPid = Binder.getCallingPid();     final long origId = Binder.clearCallingIdentity();     attachApplicationLocked(thread, callingPid);     Binder.restoreCallingIdentity(origId); }    }

调用到server端:ActivityManagerNative  ->ActivityManagerService。

继续AMS的attachApplication的分析,就执行到AMS中的对应的

attachApplicationLocked

方法中了,这个方法非常重要,接下来分析一下。

2)AMS中attachApplicationLocked方法的分析:

在attachApplicationLocked方法中,关键调用了下面这个方法:

thread.bindApplication(processName, appInfo, providers,...)//省略若干参数

说明:

这里的thread是IApplicationThread类型,而且thread是Client端,真正类型是ApplicationThreadProxy,即服务端的代理。而这个ApplicationThreadProxy是在ApplicationThreadNative中定义的。

所以,我们来分析ApplicationThreadProxy的bindApplication方法的实现。

继续分析,ApplicationThreadProxy的bindApplication方法的实现:

public final void bindApplication(String packageName, ApplicationInfo info,     ......) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeString(packageName); info.writeToParcel(data, 0); ...... //都是data.write方法   mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,  IBinder.FLAG_ONEWAY); data.recycle();}

mRemote.transact最终调用到ApplicationThreadNative中,即Service端。

3)服务端对BIND_APPLICATION_TRANSACTION的处理:

mRemote是IBinder类型,而真正的实例是ActivityThread。

原因如下:

ApplicationThreadNative是抽象类,无法实例化;

ActivityThread是继承自ApplicationThreadNative的具体类;

所以,mRemote其实是ActivityThread的实例。

然后,就是BIND_APPLICATION_TRANSACTION的处理:

mRemote.transact通过binder机制,调用到ApplicationThreadNative中去处理。

代码如下:

case BIND_APPLICATION_TRANSACTION: {     data.enforceInterface(IApplicationThread.descriptor);     String packageName = data.readString();     ApplicationInfo info =  ApplicationInfo.CREATOR.createFromParcel(data);   ......   bindApplication(packageName, info,providers, testName, profileName, profileFd, autoStopProfiler,testArgs, testWatcher, testMode, openGlTrace, restrictedBackupMode,persistent, config, compatInfo, services, coreSettings);     return true; }

这里的bindApplication是在ApplicationThread中实现的。前面已经分析过,ApplicationThread是ApplicationThreadNative的子类。所以在ApplicationThreadNative中的代码调用,其实就是ApplicationThread的代码的执行。

4)ApplicationThread的bindApplication方法:

在ApplicationThread的bindApplication方法中,最后一条语句

queueOrSendMessage(H.BIND_APPLICATION, data);

发送了message,在H 这个handler类中,对message的处理如下:

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;

接着,我们看

handleBindApplication

5) handleBindApplication的分析:

好像看到一些曙光了。再次说明一下,我们分析这部分代码的目的是:为了分析清楚一个App是如何被创建和初始化的。也就是说,Application的onCreate函数是如何被执行的。

在handleBindApplication中,关键点如下:

1. mInstrumentation的创建;

 mInstrumentation = new Instrumentation(); //如果已经创建,就不需要new了

2. Application的创建;

Application app = data.info.makeApplication(data.restrictedBackupMode, null);

3. 通过mInstrumentation的

callApplicationOnCreate

来启动App:

 mInstrumentation.callApplicationOnCreate(app);

Instrumentation.callApplicationOnCreate的实现:

到了这里,只需要一句代码即可:

public void callApplicationOnCreate(Application app) { app.onCreate();}

这样,就调用到了app的onCreate()方法了。

至此,整个分析流程结束。

4. 总结:

1. 一系列的startActivity的调用;

2. AMS(ActivityManagerService)相关的关键组件:

ActivityManager //可以认为是对ActivityManagerProxy的封装

ActivityManagerProxy //作为客户端;

ActivityManagerNative //抽象类,无法实例化;

ActivityManagerService //继承自ActivityManagerNative,具体类,作为服务端;

3. ApplicationThread相关的关键的组件:

ApplicationThreadProxy //作为客户端;

ApplicationThreadNative //抽象类,无法实例化;

ApplicationThread //继承自ApplicationThreadNative,具体类,作为服务端;

4. Instrumentation //Activity和Application的启动,都要由它来触发。

可见,从binder的角度来看,AMS和ApplicationThread的组件架构几乎一样。这是Android系统服务中典型的服务实现方式。