Android 是怎么启动一个Acitivity的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 是怎么启动一个Acitivity的相关的知识,希望对你有一定的参考价值。

可以把启动过程分为client端和server端。
一、client端在启动一个Activity时进行的工作
备注:我个人理解,client端指的是相对后台ActivityManagerService 进程来说的前台用户可见的进程,如在界面启动某一个Activity的就是Laucher进程。这里则以从home桌面启动一个Activity来分析启动过程:
(1)Launcher 这个进程的主线程,在捕获onClick点击事件后,调用 startActivitySafely 方法, startActivitySafely 方法内部调用了
startActivity 方法,然后,startActivity方法进而调用Launcher的父类Activity的 startActivity方法;
(2)Activity.startActivity方法 调用startActivityForResult 方法,传入该方法 的requestCode 参数为 -1 ,表示 Activity启动成功后,不需要执行 Lanucher.onActivityResult方法处理返回结果;startActivityForResult方法内部需要调用 Instrumentation 的 execStartActivity方法。Instrumentation 对象是用于监控应用程序和系统(主要是 Activity Manager )的交互过程。
(3)execStartActivity方法会把将要启动的Activity相关信息传送到ActivityManagerService 如果 ActivityMonitor 对启动Activity 进行检查没问题,那么会调用 ActivityManagerNative.getDault 得到ActivityManagerProxy代理对象,然后调用该代理对象的startActivity方法。;
(4)调用ActivityManagerProxy代理对象的startActivity方法实际上是调用 BinderProxy.transact向 Binder驱动发送 START_ACTIVITY_TRANSACTION命令,此时就从Lanucher进程切换到ActivityManagerService进程了。
总结上述四步:源Activity(这里是Launcher)所属进程通过一系列方法,(无论是通过Launcher来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activit),都通过Binder进程间通信进入到ActivityManagerService进程中,并且调用ActivityManagerService.startActivity接口;

二、Lanucher进程处理Activity的启动请求,就是Client端的工作,传递给 Server端的 ActivityManagerService 后。就是ActivityManagerService 进程的处理过程 了。
处理过程将分为 7个阶段
1、第一阶段——预启动检查
这个阶段,主要工作是检查是否有权限启动该Activity,查询系统中是否存在指定Intent的Activity, 检查Intent是否正确,检查当前能否切换Activity,各种检查通过后创建目标Activity的ActivityRecord, 判断是否有可复用的Task 或者Activity ,有则关联ActivityRecord,无则新建Task ,更新 ActivityManagerService中Task的数量,检查回退栈顶是否有显示的Activity,有则暂停。
2、第二阶段——暂停
这个阶段的主要工作就是暂停启动目标 Activity的源Activity,比如,我是从Actvity A启动Activity B的,那么在启动B之前需要把A暂停,
针对暂停的Activity的后续处理,要么是执行destroy 操作,要么是存入等待stop列表;
3、第三阶段——创建目标Activity所运行的进程
准备切换动画,查询ActivityManagerService 的mProcessNames变量中是否存在指定的进程信息,有则复用,直接启动Activity,无则通过zygote启动一个新的进程。进程启动超时时间一般是10s。
4、第四阶段——加载应用程序Activity
进程入口是 ActivityThread 的main方法,main方法里的主要工作是设置临时进程名,创建 UI主线程ActivityThread ,并调用其attach方法,最后进入主线程的消息循环。接下来的工作是为低内存设备禁用硬件加速,创建应用程序对应的Application, 并初始化,安装 Content Provider,执行Instrumentation的onCreate方法,执行Application的 onCreate方法。
5、第五阶段——显示Acitivity
在ActivityManagerService 所在进程向应用程序主线程的消息循环发送 LANUCHER_ACTIVITY消息,然后在主线程中回调Activity生命周期的onCreate, onStart,onResume等方法来显示 Activity,onResume方法执行完毕后,需要先把当前显示Activity所在的Task加入最近Task列表,然后才返回ActivityManagerService作后续处理。(在onResume方法之前,还可能会先回调onNewIntent 和 onActivityResult方法)

6、第六阶段——处理处于空闲状态的Activitiy
包括移除ActivityStack消息循环中的超时MSG,停止待停止列表总得Activity,销毁待销毁的Activity,如果是系统启动阶段,还要发送一个ACTION_BOOT_COMPLETEED广播,回收待回收应用程序进程等。最重要的一个操作就是停止源Activity 。

备注:此文是读书所得,主要归纳于老罗的《Android 源代码情景分析》和杨云君老师的《Android的设计与实现I》。
参考技术A 1、在一个Activity中调用startActivity()方法。这种方法
2、在一个Activity中调用startActivityRequest()方法。
重写onActivityResult方法,用来接收B回传的数据。
在B中回传数据时采用setResult方法,并且之后要调用finish方法。

第一种方法简单直接。但是如果A调用B,并传递数据,同时B对数据处理后又返回给A,A再将数据显示出来。碰到这种情况,用第一种方法需要在A的onCreate()里面判断是第一次生成的界面,还是由B打开的A。这样比较麻烦,用第二种方法就简单了,在A的onCreate()只用写一次生成的界面的内容。在A的onActivityResult方法里放B处理完数据后的内容就可以了。

android fragment相互切换的时候生命周期怎么走

Fragment的生命周期初探:
因为Fragment必须嵌入在Acitivity中使用,所以Fragment的生命周期和它所在的Activity是密切相关的。
如果Activity是暂停状态,其中所有的Fragment都是暂停状态;如果Activity是stopped状态,这个Activity中所有的Fragment都不能被启动;如果Activity被销毁,那么它其中的所有Fragment都会被销毁。
但是,当Activity在活动状态,可以独立控制Fragment的状态,比如加上或者移除Fragment。
当这样进行fragment transaction(转换)的时候,可以把fragment放入Activity的back stack中,这样用户就可以进行返回操作。
使用Fragment时,需要继承Fragment或者Fragment的子类(DialogFragment, ListFragment, PreferenceFragment, WebViewFragment),所以Fragment的代码看起来和Activity的类似。
每当创建一个Fragment时,首先添加以下三个回调方法:
onCreate():系统在创建Fragment的时候调用这个方法,这里应该初始化相关的组件,一些即便是被暂停或者被停止时依然需要保留的东西。 onCreateView():当第一次绘制Fragment的UI时系统调用这个方法,该方法将返回一个View,如果Fragment不提供UI也可以返回null。注意,如果继承自ListFragment,onCreateView()默认的实现会返回一个ListView,所以不用自己实现。 onPause():当用户离开Fragment时第一个调用这个方法,需要提交一些变化,因为用户很可能不再返回来。
将Fragment加载到Activity当中有两种方式:
方式一:添加Fragment到Activity的布局文件当中 方式二:在Activity的代码中动态添加Fragment(荐)
第一种方式虽然简单但灵活性不够。添加Fragment到Activity的布局文件当中,就等同于将Fragment及其视图与activity的视图绑定在一起,且在activity的生命周期过程中,无法切换fragment视图。
第二种方式比较复杂,但也是唯一一种可以在运行时控制fragment的方式(加载、移除、替换)。
参考技术A Fragment的生命周期初探:
因为Fragment必须嵌入在Acitivity中使用,所以Fragment的生命周期和它所在的Activity是密切相关的。
如果Activity是暂停状态,其中所有的Fragment都是暂停状态;如果Activity是stopped状态,这个Activity中所有的Fragment都不能被启动;如果Activity被销毁,那么它其中的所有Fragment都会被销毁。
但是,当Activity在活动状态,可以独立控制Fragment的状态,比如加上或者移除Fragment。
当这样进行fragment transaction(转换)的时候,可以把fragment放入Activity的back stack中,这样用户就可以进行返回操作。
使用Fragment时,需要继承Fragment或者Fragment的子类(DialogFragment, ListFragment, PreferenceFragment, WebViewFragment),所以Fragment的代码看起来和Activity的类似。
每当创建一个Fragment时,首先添加以下三个回调方法:
onCreate():系统在创建Fragment的时候调用这个方法,这里应该初始化相关的组件,一些即便是被暂停或者被停止时依然需要保留的东西。 onCreateView():当第一次绘制Fragment的UI时系统调用这个方法,该方法将返回一个View,如果Fragment不提供UI也可以返回null。注意,如果继承自ListFragment,onCreateView()默认的实现会返回一个ListView,所以不用自己实现。 onPause():当用户离开Fragment时第一个调用这个方法,需要提交一些变化,因为用户很可能不再返回来。
将Fragment加载到Activity当中有两种方式:
方式一:添加Fragment到Activity的布局文件当中 方式二:在Activity的代码中动态添加Fragment(荐)
第一种方式虽然简单但灵活性不够。添加Fragment到Activity的布局文件当中,就等同于将Fragment及其视图与activity的视图绑定在一起,且在activity的生命周期过程中,无法切换fragment视图。
第二种方式比较复杂,但也是唯一一种可以在运行时控制fragment的方式(加载、移除、替换)。

以上是关于Android 是怎么启动一个Acitivity的的主要内容,如果未能解决你的问题,请参考以下文章

Android_Acitivity

android开发问题:如何在当前Acitivity中用代码获取上一个Activity名称?

Android(Intent 学习)

android fragment相互切换的时候生命周期怎么走

Acitivity.xml

Android 关于Acitivity 的setFlag以及launchmode的总结