Android Activity的启动与创建

Android Activity的启动与创建



在学习Android的路上,总会经历一个阶段。我们在开发了很多功能,解决了很多BUG之后,已经能应付公司的开发任务了。却对Android最基本的原理都语焉不详,知之甚少。

今天我们来看看一个Android应用是如何启动、创建和展示的。


Android系统相关进程以及其相互之间的交互。
  • 相关的进程简介

    • Init进程:Android是基于linux内核的系统,在linux系统中所有进程都是由Init进程fork出来的。

    • Zygote进程:在Android系统中,所有的应用程序进程以及系统服务进程都是由Zygote进程fork出来的。

    • SystemServer进程:简而言之就是初始化各类服务,其中包括Native服务初始化,Java层服务初始化(ServerThread类 )等等。

    • PackageManagerService:由ServerThread启动,负责管理系统的Package,包括APK的安装,卸载,信息的查询等等。它的功能非常的多,也非常的强大。

    • ActivityManagerService:简称AMS,单例模式。由ServerThread启动,用于管理所有的Activity的生命周期,也管理着系统的service、broadcast以及provider等。

  • 相关进程间的关系:

    • 1、系统启动时,Init进程会创建Zygote进程。
    • 2、Zygote进程会首先创建一个SystemServer进程。
    • 3、SystemServer进程会启动一个ServerThread线程。
    • 4、ServerThread线程分别启动PackageManagerService和ActivityManagerService。
    • 5、当需要在一个新的进程中启动一个Activity或者Service时ActivityManagerService通过socket通信发送消息给Zygote进程,使其fork出相应的新进程。
    • 6、ActivityManagerService和应用进程之间通过binder通信,以此实现对Android应用的管理。

首先看看Android系统和我们应用息息相关的进程和相互之间的交互


应用的启动流程

1、应用第一次启动时,会启动一个新进程,该进程用应用的包名作为进程名。该进程创建完成后,会加载ActivityThread类并执行其main()方法。并支持Binder进行进程间通信。

2、main()方法作为进程的入口,以及支持Binder通信都是在进程初始化时实现的。

3、ActivityThread为本应用的主线程,即UI线程。这个main()方法是进程实现消息循环的地方,也会找到该应用与主Activity的映射关系,并将其启动。


  • 从应用主线程(ActivityThread)向系统进程(AMS)通信的过程,代码从Activity.java开始,分四步。

    • 第一步:startActivity()。通过此调用,为应用程序重写本方法时的兼容性做考虑。

      @Override
      public void startActivity(Intent intent, @Nullable Bundle options) {
          if (options != null) {
              startActivityForResult(intent, -1, options);
          } else {
              startActivityForResult(intent, -1);
          }
      }
    • 第二步:startActivityForResult()。execStartActivity()方法来继续启动Activity,ActivityThread中的sendActivityResult()方法用于跟踪execStartActivity()方法的执行结果,并用handler以消息的形式发送出去。

      public void startActivityForResult(Intent intent, int requestCode, @Nullable 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());
              }
              ....
       }
    • 第三步:execStartActivity()。这里实现应用进程和系统进程之间的交互;这里调用 ActivityManagerNative.getDefault()的startActivity()方法是通过代理模式,由ActivityManagerProxy实现接口IActivityManager中的startActivity()方法。

      public ActivityResult execStartActivity(
              Context who, IBinder contextThread, IBinder token, Activity target,
              Intent intent, int requestCode, Bundle options) {
          IApplicationThread whoThread = (IApplicationThread) contextThread;
          .
          //判断是够该Activity已存在的逻辑,略。
          .
          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;
      }
    • 第四步:接口IActivityManager中的startActivity()方法的实现,旨在调用ActivityManagerService.startActivity()方法。以实现应用程序向AMS发送Activity创建的消息,交AMS对Activity的生命周期等进行管理。

      class ActivityManagerProxy implements IActivityManager{
      public ActivityManagerProxy(IBinder remote) {
          mRemote = remote;
      }
      public IBinder asBinder(){
          return mRemote;
      }
      
      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 {
              .
              //调用AMS的startActivity()方法,略。
              .
          }
      }

  • 系统进程(AMS)接收到startActivity消息后执行了什么?如何反馈给应用主线程(ActivityThread):

    • ActivityManagerService的startActivity()方法执行到Activity创建成功到反馈给应用进程是一个十分繁复的过程,因为这是系统进程的任务,这里就不详解了。感兴趣的童鞋请迈入 传送门

    • 细心的小伙伴们有没有发现上诉第三步中的一个变量IApplicationThread whoThread,并将其作为参数向下传递到了AMS中,这个IApplicationThread接口是什么?它反向扮演着IActivityManager的角色,即从系统进程(AMS)向应用主线程(ActivityThread)通信的接口,它与IActivityManager对应,也是使用代理模式,由ApplicationThreadProxy代理。


  • 应用进程和AMS之间通信的两个重要接口简介:
    嗷嗷嗷啊

    • IActivityManager接口:由上图可见,本接口用于ActivityThread向AMS通信,调用。源码中这样描述:
    // System private API for talking with the activity manager service.  This provides calls from the application back to the activity manager.
    
    public interface IActivityManager extends IInterface {
    public int startActivity(IApplicationThread caller...参数略) throws RemoteException;
    public int startActivityAsUser(IApplicationThread caller...参数略) throws RemoteException;
    public int startActivityAsCaller(IApplicationThread caller...参数略) throws RemoteException;
    public WaitResult startActivityAndWait(IApplicationThread caller...参数略) throws RemoteException;
           .
           .
           .
    }
    
    • IApplicationThread接口:由上图可见,本接口用于AMS向ActivityThread通信,调用。源码中这样描述:

      // System private API for communicating with the application.  This is given to the activity manager by an application  when it starts up, for the activity manager to tell the application about things it needs to do.application back to the activity manager.
      
      public interface IApplicationThread extends IInterface {
      void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
              int configChanges, boolean dontReport) throws RemoteException;
      void scheduleStopActivity(IBinder token, boolean showWindow,
              int configChanges) throws RemoteException;
      void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
      void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
      void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)
              throws RemoteException;
      void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
             .
             .
             .
      }
      
    • 英文好的小伙伴可以读一下官方给出的接口描述,能更清晰的了解其用途。由上面两段代码很清晰的能看出这两个接口的职能。即IActivityManager代表应用进程向AMS派发任务,IApplicationThread代表AMS对应用进程的Activity进行管理,反馈。


未完待续

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值