当前位置:   article > 正文

Android应用程序启动流程之从startActivity开始_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方法:

  1. queueOrSendMessage(H.LAUNCH_ACTIVITY, r); ->
  2. mH.sendMessage(msg);
  3. ->
  4. H.handleMessage()中,有:
  5. case LAUNCH_ACTIVITY: {
  6. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
  7. ActivityClientRecord r = (ActivityClientRecord)msg.obj;
  8. r.packageInfo = getPackageInfoNoCheck(
  9. r.activityInfo.applicationInfo, r.compatInfo);
  10. handleLaunchActivity(r, null);
  11. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  12. }

handleLaunchActivity方法调用了

performLaunchActivity

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

  1. //performLaunchActivity方法的实现:
  2. Activity activity = null;
  3. try {
  4. java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
  5. activity = mInstrumentation.newActivity(
  6. cl, component.getClassName(), r.intent);
  7. StrictMode.incrementExpectedActivityCount(activity.getClass());
  8. r.intent.setExtrasClassLoader(cl);
  9. if (r.state != null) {
  10. r.state.setClassLoader(cl);
  11. }
  12. }
  13. ......
  14. Application app = r.packageInfo.makeApplication
  15. ......
  16. activity.attach
  17. ......
  18. mInstrumentation.callActivityOnCreate(activity, r.state);

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

callActivityOnCreate

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

2.3 分支二:startProcessLocked的执行

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

在Process.java中,有

  1. argsForZygote.add("--runtime-init");
  2. argsForZygote.add("--setuid=" + uid);
  3. argsForZygote.add("--setgid=" + gid);
  4. ......
  5. zygoteSendArgsAndGetResult(argsForZygote)

 openZygoteSocketIfNeeded函数的实现:

  1. try {
  2. sZygoteSocket = new LocalSocket();
  3. sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,
  4. LocalSocketAddress.Namespace.RESERVED));
  5. sZygoteInputStream
  6. = new DataInputStream(sZygoteSocket.getInputStream());
  7. sZygoteWriter =
  8. new BufferedWriter(
  9. new OutputStreamWriter(
  10. sZygoteSocket.getOutputStream()),
  11. 256);
  12. Log.i("Zygote", "Process: zygote socket opened");
  13. sPreviousZygoteOpenFailed = false;
  14. break;
  15. } catch (IOException ex) {
  16. ......
  17. }

分析:

创建一个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函数:

  1. public static void main(String[] args) {
  2. ......
  3. Looper.prepareMainLooper();
  4. if (sMainThreadHandler == null) {
  5. sMainThreadHandler = new Handler();
  6. }
  7. ActivityThread thread = new ActivityThread();
  8. thread.attach(false);
  9. AsyncTask.init();
  10. if (false) {
  11. Looper.myLooper().setMessageLogging(new
  12. LogPrinter(Log.DEBUG, "ActivityThread"));
  13. }
  14. Looper.loop();
  15. throw new RuntimeException("Main thread loop unexpectedly exited");
  16. }

 thread.attach()的实现:

  1. IActivityManager mgr = ActivityManagerNative.getDefault();
  2. 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, 如下:

  1. public void attachApplication(IApplicationThread app) throws RemoteException
  2. {
  3. Parcel data = Parcel.obtain();
  4. Parcel reply = Parcel.obtain();
  5. data.writeInterfaceToken(IActivityManager.descriptor);
  6. data.writeStrongBinder(app.asBinder());
  7. mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
  8. reply.readException();
  9. data.recycle();
  10. reply.recycle();
  11. }

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

2. server端:

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

  1. case ATTACH_APPLICATION_TRANSACTION: {
  2. data.enforceInterface(IActivityManager.descriptor);
  3. IApplicationThread app = ApplicationThreadNative.asInterface(
  4. data.readStrongBinder());
  5. if (app != null) {
  6. attachApplication(app);
  7. }
  8. reply.writeNoException();
  9. return true;
  10. }

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

  1. public final void attachApplication(IApplicationThread thread) {
  2. synchronized (this) {
  3. int callingPid = Binder.getCallingPid();
  4. final long origId = Binder.clearCallingIdentity();
  5. attachApplicationLocked(thread, callingPid);
  6. Binder.restoreCallingIdentity(origId);
  7. }
  8. }

调用到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方法的实现:

  1. public final void bindApplication(String packageName, ApplicationInfo info,
  2. ......) throws RemoteException {
  3. Parcel data = Parcel.obtain();
  4. data.writeInterfaceToken(IApplicationThread.descriptor);
  5. data.writeString(packageName);
  6. info.writeToParcel(data, 0);
  7. ...... //都是data.write方法
  8. mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
  9. IBinder.FLAG_ONEWAY);
  10. data.recycle();
  11. }

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

3)服务端对BIND_APPLICATION_TRANSACTION的处理:

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

原因如下:

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

ActivityThread是继承自ApplicationThreadNative的具体类;

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

然后,就是BIND_APPLICATION_TRANSACTION的处理:

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

代码如下:

  1. case BIND_APPLICATION_TRANSACTION:
  2. {
  3. data.enforceInterface(IApplicationThread.descriptor);
  4. String packageName = data.readString();
  5. ApplicationInfo info =
  6. ApplicationInfo.CREATOR.createFromParcel(data);
  7. ......
  8. bindApplication(packageName, info,
  9. providers, testName, profileName, profileFd, autoStopProfiler,
  10. testArgs, testWatcher, testMode, openGlTrace, restrictedBackupMode,
  11. persistent, config, compatInfo, services, coreSettings);
  12. return true;
  13. }

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

4)ApplicationThread的bindApplication方法:

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

queueOrSendMessage(H.BIND_APPLICATION, data);

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

  1. case BIND_APPLICATION:
  2. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
  3. AppBindData data = (AppBindData)msg.obj;
  4. handleBindApplication(data);
  5. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  6. 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的实现:

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

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

这样,就调用到了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系统服务中典型的服务实现方式。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/680189
推荐阅读
相关标签
  

闽ICP备14008679号