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

来源:互联网 发布:苍蝇水在淘宝怎么买 编辑:程序博客网 时间:2024/05/16 07:10

想想我们在客户端是如何启动一个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
原创粉丝点击