简述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是怎样和系统进行交互的。
- 简述Activity的启动流程(类的创建)
- 简述Activity的启动流程(界面显示)
- activity启动流程简述
- Activity的启动和创建流程
- Activity的启动流程
- Activity的启动流程
- Activity的启动流程
- Activity的启动流程
- activity的启动流程
- Activity的启动流程
- Activity的启动流程
- Activity的启动流程
- Activity的启动流程
- Activity的启动流程
- Activity的启动流程
- Activity的启动流程
- Activity的启动流程
- Activity的启动流程(二)
- apache-activemq(四)
- Android基础——3.布局&Logcat
- UILabel数字变化增加动画
- 第十二周项目1-实现复数类中的运算符重载(1.2友元函数)
- C++中typedef的用法总结
- 简述Activity的启动流程(类的创建)
- Restful形式接口文档生成之Swagger与SpringMVC整合手记
- ecshop文件结构名称手册
- 向上转型,重写基类函数,访问权限,循环依赖---图片为什么上传不了??
- 2.Linux的ACL权限
- jboss eap 6.4部署项目问题
- android-support-multidex解决Dex 文件方法数超过65536
- python对于中文编码处理的几种方式
- 剑指offer 面试题(打印1到n最大的n位整数)(6)