简述Activity的启动流程(类的创建)

想想我们在客户端是如何启动一个Activity的
1.清单文件中声明
2.通过startActivity()启动
这里我主要想分析一下第二种启动方法,暂时不想看解析xml的源码。
直接进入Activity的startActivity()方法,进入Instrumentation的execStartActivity()方法

  try {
            ......
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
            ......
        } catch (RemoteException e) {
        }

ActivityManagerNative(写入)是一个Binder,专门用来和运行在服务端的AmS进行IPC通信。
在这里简述一下AmS和Activity有关的功能:
统一调度各应用程序的Activity.所有的应用程序要启动Activity的话,都要先报告给AmS,他会决定该Activity是否可以启动,如果可以,它再发消息给应用程序启动指定的Activity. ——《Android内核剖析》
此时,启动Activity的消息已经发送到了AmS,那么我们在哪里收到AmS发送给应用程序的消息呢?
客官们可以先看看知乎上的一个问题
https://www.zhihu.com/question/34652589/answer/90662131?from=profile_answer_card
我们都知道主线程的概念,也许知道Android程序的入口点是ActivityThread类的main()方法。弄出了一个轮询器,然后不断的从消息队列中拿消息,执行,如果没有消息的话,就处于”休眠” 状态,并不会消耗CPU资源。
关于UI线程
每一行代码都是在线程中执行的,可以这么说,执行ActivityThread的线程就是UI线程。执行完main()方法后,主线程此时就处于轮询状态,接受消息,执行消息中的内容,他就干那些事儿。
可是,我们刚刚说到的接收AmS发来的消息是怎么回事儿

  public static void main(String[] args) {
        ......
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false); //创建了一个新的线程
        ......
        Looper.loop();
    }

和AmS通信是IPC操作,需要不断的从Binder读取数据,这一操作,肯定不是在UI线程做的,那Android就没法弄了啊。
看看main()函数的代码thread.attach(false)

/**将ApplicationThread作为该进程/应用程序的唯一识别(暂时不明白有什么用)
*/
    RuntimeInit.setApplicationObject(mAppThread.asBinder());
    //这里的实现类是ActivityManagerNative
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
            /**
            *将发送Binder和接受Binder关联起来,因为系统收到消息后必须
            *回发一个消息,系统后面会根据这个标识把数据发送出去
            *对应的Binder才能收到数据
            */
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }

这里写图片描述
注:此图来自知乎大神https://www.zhihu.com/people/gityuan
注意图中的箭头,收消息和发消息是分开的,我们在发消息的时候必须带上一个标识,系统收到这个消息后会回发一个消息,那客户端究竟怎么拿到这个消息呢?这个表示就派上用场了,客户端会调用相应的Binder去读取这个消息,这样才不会弄混淆。

下面我们就来看看ActivityThread的方法

  public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig,...)
  {
      ......
      sendMessage(H.LAUNCH_ACTIVITY, r);//发送一个启动Activity的消息
      ......
  }

UI线程Handler的handleMessage()方法

  public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                ......
                    handleLaunchActivity(r, null);
                ......
                }
  }                 

后面的事情是很容易想到了,利用反射创建一个Activity对象,然后再调用他的各种onCreate(),onResume()方法

 try {
            ......
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ......
        } 

这就是Activity启动的一个简单分析,最重要的是理解App是怎样和系统进行交互的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值