1. Activity介绍

Acitivity在安卓开发中非常重要,他很像Java桌面开发中的JFrame,在MVC模式中属于Controller,一般一个应用程序通常由多个松耦合关系的activities组成,一个Activity是一个应用程序组件,控制一个View,用户可以用来交互。通常,当第一次启动应用程序的时候呈现给用户的那个activity被指定为 main activity。每一个activity然后可以启动另一个activity为了完成不同的动作。每一次一个activity启动,前一个activity就停止了,但是系统保留activity在一个栈上。当一个新activity启动,它被推送到栈顶,取得用户焦点。所以,当用户完成当前activity然后点击back按钮,它被弹出栈(并且被摧毁),然后之前的activity恢复。Activity的生命周期由Acitivity Manager管理。

A. Activity的种类有半透明的、悬浮的、全屏的。半透明、悬浮可以通过设置theme实现。它经常使用的类有Activity、ListActivity、ExpandableListActivity。

B. Android中,当应用程序运行环境改变时,设备的配置环境也许会发生变化(比如屏幕的旋转,键盘可用性的改变,语言的改变)。但是这些变化发生时,Android系统会重启Activity(onDestroy()将被调用,随后再调用onCreate()来创建Activity)。之所以这样设计,是想通过重新加载Activity来加载和新的配置环境相对应的资源,以便Activity能很好的适配新的配置环境。配置改变会导致Activity重启,可以定义android:configChanges来阻止重启。

C. 为了很好的处理Activity的重启,应该在Activity销毁前的系统回调函数中onSaveInstanceState() 保存其状态,然后在其重新被构建时的系统回调函数 onCreate() oronRestoreInstanceState()中,根据前面保存的状态来进行相应的设置。

2. Activity生命周期

要想能够自如的玩转Activity,深入的了解Activity的生命周期是必须的。

Activity从创建到消亡有活动、暂停、终止、非活动状态几种状态。

为了方便监控这些状态的变化,activity提供了事件处理方法,状态的变化会触发Activity的对应事件处理方法。

这张图完美的诠释了事件发生顺序。

从图上可以看到,有三个生存期:完整生存期、可见生存期、活动状态生存期。

完整生存期是从onCreate调用到onDestroy调用完成的状态,有时候不会调用destroy(例如断电)。

可见生存期是Activity可以被用户看到的时期(但是不一定有焦点):从onStart到onStop。

活动生存期是Activity可以与用户交互的时期:从onResume到onPause。

A. 当activity创建时,首先onCreate方法被调用,此时,可以调用setContentView设置Activity显示的View或者ViewGroup,也就是初始化UI和Activity的过程。

B. 如果这个Activity之前被运行时pause过(也就说显示过),那么onRestoreInstanceState会被调用,用来恢复界面状态(从Bundle)

C. 之后,可见生存期开始,onStart会被调用,可以开始启动UI更新了,可以启动线程、broadcastReceiver、传感器等。

D. 之后,活动状态开始,调用onResume,界面可以交互了。

E. 当activity要被要被stop之前(有时,非主动,被运行时因为内存问题stop),会调用onSaveInstanceState,如果该Activity被运行时终止并重启,那么被保存到bundle中的数据会被传递到oncreate和onRestoreInstanceState. 所以最好在oncreate里面判断一下是不是重新恢复创建的。

F. 当该启动了其他的Activity时,onPuase会被调用,此时可以挂起不需要更新的UI更新、线程和CPU密集的进程。

G. 当activity完全被遮盖时,onStop会被调用,此时应该挂起UI更新、线程和处理、传感器、broadcastReceiver。

H. 生命周期结束则会调用onDestroy,回收各项资源。

I. 图中onSave有误,大部分情况下都是在onPause后,onStop前。

当然,在Activity级别,也有像上文Application那样的事件处理函数。

事件处理函数

 

onLowMemory

低内存事件触发,无参数

onTrimMemory(int)

OnLowMemory是在最后一个后台进程被杀时调用,一般情况是low memory killer 杀进程后触发;而OnTrimMemory的触发更频繁,每次计算进程优先级时,只要满足条件,都会触发。

onConfigurationChanged(Configuration )

配置改变处理

3. Activity task和启动模式

在Android系统中,Activity组件的动态运行是通过task的,这种组织方法是面向组件开发的一种体现,比进程化得组织便利很多,task是将组件之间的连接,从进程概念的细节中剥离出来。同一个应用程序的不同Activity不一定在同一个task中,不同应用程序的activity也可以在同一个task中。Task其实是一个栈形式组织的Activity集合。

launchMode

<activity>元素的launchMode属性可以设置四种不同的加载模式:

A. standard (默认模式):会在当前调用者的task栈顶压入启动的activity。

B. singleTop:基本上于standard一致,仅在请求的Activity 正好位于栈顶时,有所区别。此时,配置成singleTop的Activity,不再会构造新的实例加入到Task栈中,而是将新来的Intent发送到栈顶Activity中,栈顶的Activity可以通过重载 onNewIntent来处理新的Intent。

C. singleTask:另辟Task。 标志为singleTask的Activity,最多仅有一个实例存在,并且,位于以它为根的Task中。所有对该Activity的请求,都会跳到该Activity的Task中展开进行。但是,需要设置singleTask的独立taskAffinity。

D. singleInstance:另辟Task。在大部分时候singleInstance与singleTask完全一致,唯一的不同在于,singleInstance的Activity,是它所在栈中仅有的一个Activity,如果涉及到的其他Activity,都移交到其他Task中进行。

taskAffinity

<activity>元素的taskAffinity属性,表示亲属关系,它倾向于将taskAffinity属性相同的Activity,扔进同一个Task中(即使是不同应用程序的activity)。不过,它的约束力,较之launchMode而言,弱了许多。只有当中的 allowTaskReparenting设置为true,或是调用方将Intent的flag添加 FLAG_ACTIVITY_NEW_TASK属性时才会生效。如果在manifest中没有对Activity的android:taskAffinity进行配置,每个Activity都采用和Application相同的taskAffinity;这也就意味着,同一个Application中的所有Activity的taskAffinity在默认情况下是相同的。

示例:

A.两个Activity:MainActivity和SubActivity,先启动MainActivity,MainActivity启动SubActivity, SubActivity启动SubActivity。Standard模式。最后的任务栈如下所示。

B. 两个Activity:MainActivity和SubActivitySingleTop,先启动MainActivity,MainActivity 启动single top 模式的SubActivitySingleTop, SubActivitySingleTop启动single top 模式SubActivitySingleTop。最后的任务栈如下所示。

C. 两个Activity:MainActivity和SubActivitySingleTask,先启动MainActivity,MainActivity 启动single task模式的SubActivitySingleTask, SubActivitySingleTask启动single task 模式SubActivitySingleTask。注意,启动两次SubActivitySingleTask。最后的任务栈如下所示。

从这个图看出,这与SingleTop表现一样啊,为什么?看下面。

D.两个Activity:MainActivity和SubActivityRealSingleTask,先启动MainActivity,MainActivity 启动single task模式的SubActivityRealSingleTask, SubActivityRealSingleTask启动single task 模式SubActivitySingleTask。注意,启动两次SubActivityRealSingleTask。与C不同的是,此次我设置了独立的taskAffinity这时候最后的任务栈如下所示。

罗升阳博客上说:“

1. 设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的任务存在;如果存在这样的任务,它就会在这个任务中启动,否则就会在新任务中启动。因此,如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。

2. 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。

E. 三个Activity:MainActivity、SubActivityRealSingleTask(single task,设置了affinity)和SubActivityInter,先启动MainActivity,MainActivity 启动SubActivityRealSingleTask, SubActivityRealSingleTask启动standard模式SubActivityInter。这时:

然后SubActivityInter启动了SubActivityRealSingleTask。这时候最后的任务栈如下所示。

F. 三个Activity:MainActivity(single top)、SubActivitySingleInstance(single Intantce,未设置了affinity)和SubActivityInter2(standard)。MainActivity先启动SubActivitySingleInstance。图下

SubActivitySingleInstance启动SubActivityInter2,如下

SubActivityInter2启动MainActivity

注意:如果launchMode设置为standard,Affinity是无效的。

Intent flags:(启动Activity使用),这个很坑

FLAG

解释

FLAG_ACTIVITY_NEW_TASK

设置了这个flag,新启动Activity就会被放置到一个新的任务当中

FLAG_ACTIVITY_CLEAR_TOP

要启动的Activity如果在当前Task中已经存在,就清除掉上面所有的Activity

FLAG_ACTIVITY_SINGLE_TOP

与Single Top类似

等等等等

任务清理

如果用户离开一个任务很长一段时间,系统会清理该任务中除了根activity之外的所有activity。不过可以用Activity以下属性控制这种行为:

alwaysRetainTaskState

一直保留任务状态。如果一个任务的根activity中此属性设置为“true”,则上述默认行为不会发生。任务将在很长的一段时间内保留它堆栈内的所有activity。

clearTaskOnLaunch

每次都会清空task,仅留下根Activity. 如果一个任务的根activity中此属性设置为“true”,则每当用户离开这个任务和返回它的时候,堆栈都会被清空至只留下根Activity。这正巧与alwaysRetainTaskState相反。

finishOnTaskLaunch

仅作用于单个的activity,而不是整个的task。而且它可以使任意activity都被清理,甚至根activity也不例外。当它设置为“true”的时候,只要离开这个task栈, 则系统会马上清除这个Activity, 不管这个Activity在堆栈的任何位置。

任务栈要各个参数之间配合使用

4. Activity之切换

A. 直接调用,不需要知道结果,采用startActivity

B. 直接调用,需要知道结果,采用startActivityForResult(),并且重载onActivityResult方法。比较注意的是,当用户按back键的时候,系统会将resultCode置为RESULT_CANCELED,无法传递数据。

Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");

setResult(Activity.RESULT_OK, result);

finish();

5. Activity系统调度

Activity的调度是依靠安卓框架中的Activity Manager Service。 framework框架中采用C/S的方式实现由后台服务ActivityManagerService来管理具体的Acitivity实例。

MainActivity的启动过程(根Activity)

A. Launcher组件想ActivityManagerService发送一个启动MainActivity组件的进程间通信请求。(Binder)

B. ActivityManagerService首先将要启动的MainActivity组件信息保存下来,然后像Launcher组件发送一个进入中止状态的进程间通信请求(Binder).

C. Launcher组件进入中止状态后,就会向ActivityManagerService报告自己中止状态已经进入。然后ActivityManagerService继续执行启动MainActivity。

D. ActivityManagerService发现运行MainActivity组件的进程不存在,他会启动一个进程。

E. 新进程启动完成后,就会给ActivityManagerService发送一个启动完成的通信,ActivityManagerService继续执行启动动作。

F. ActivityManagerService将第二步保存的MainActivity组件的信息发送给那个新进程,让他启动MainActivity组件。每个组件都是一个TaskRecord.

子组件启动过程

A. MainActivity组件向ActivityManagerService发送一个启动SubActivity的进程间通信请求。

B. ActivityManagerService将SubActivity的信息保存下来,然后向MainActivity发送一个进入终止状态的进程间通信请求。

C. MainActivity进入中止状态后,通过Binder报告已进入中止状态给ActivityManagerService。ActivityManagerService继续执行启动。

D. A发现运行Sub的进程已经存在,那么就将SubActivity的信息发送给那个进程,那个进程启动该组件。

Android应用程序进程创建严重依赖于Zygote进程(zygote是受精卵的意思,内涵),Zygote进程在内部拥有一个虚拟机实例,所以Zygote可以通过复制自身来快速创建虚拟机示例。创建出的 每个应用进程都拥有一个虚拟机(用来执行组件)、一个Binder线程池和一个消息循环(进程间通信)。

原创, 转载注明出处哦:http://www.cnblogs.com/stonehat/p/5947678.html

【原创】菜鸟版Android 笔记2- Activity的更多相关文章

  1. 【原创】菜鸟版Android 笔记1- Android架构和Application

    Android架构 图1 Android架构自上而下名称为应用层.应用框架层.运行库和Adroid虚拟机层. Linux内核层. 1. 应用层 应用层像一座大厦里面的砖瓦.我们所做的开发基本上都在应用 ...

  2. [Android笔记1]Activity+Layout+Button

    线性布局(LinearLayout)是指view对象在父view中可按水平或垂直方向线性排列. 相对布局(RelativeLayout)是指view对象的排列依赖于各对象之间的相对位置. 下面是展示两 ...

  3. Android菜鸟的成长笔记(10)——使用Bundle在Activity之间传值

    原文:[置顶] Android菜鸟的成长笔记(10)——使用Bundle在Activity之间传值 前面我们了解了如何启动一个Activity,一个Activity在启动另外一个Activity的时候 ...

  4. Android菜鸟的成长笔记(7)——什么是Activity

    原文:[置顶] Android菜鸟的成长笔记(7)——什么是Activity 前面我们做了一个小例子,在分析代码的时候我们提到了Activity,那么什么是Activity呢? Activity是An ...

  5. Android菜鸟的成长笔记(1)——Android开发环境搭建从入门到精通

    原文:Android菜鸟的成长笔记(1)--Android开发环境搭建从入门到精通 今天在博客中看到好多Android的初学者对Android的开发环境的搭建不熟悉而导致不能进行学习,所以我决定自己写 ...

  6. Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上)

    原文:[置顶] Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上) 我们在用手机的时候可能会发现,即使应用被放到后台再返回到前台数据依然保留(比如说我们正在玩游戏,突然电话 ...

  7. Android菜鸟的成长笔记(13)——异步任务(Async Task)

    原文:[置顶] Android菜鸟的成长笔记(13)——异步任务(Async Task) Android的UI线程主要负责处理用户的事件及图形显示,因此主线程UI不能阻塞,否则会弹出一个ANR(App ...

  8. Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue

    原文:[置顶] Android菜鸟的成长笔记(12)——Handler.Loop.MessageQueue 当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要 ...

  9. Android菜鸟的成长笔记(11)——Android中的事件处理

    原文:[置顶] Android菜鸟的成长笔记(11)——Android中的事件处理 Android提供了两种方式来处理事件,一个是基于回调的事件处理,另一个是基于监听的事件处理,举个例子: 基于回调的 ...

随机推荐

  1. 【MySQL笔记】: unable to connect to remote host. catalog download has failed.

    安装完MySQL之后,它每天凌晨启动一个Intaller任务,甚是烦人:   这是一个Windows的计划服务,在这里删除即可,开始/附件/系统工具/任务计划程序,把mysql的定时任务计划取消/删除 ...

  2. JQurey中getJSON方法错误回调方法

    1.使用try...catch实现 2.换$.ajax 3.JQuery 1.5+可以这样使用: $.getJSON("example.json", function() { al ...

  3. CHBTC

    蛙人高频交易拆单策略-带手续费拆单策略及原理说明 - 王宇 warensoft - 博客园 CHBTC

  4. tcpreplay 发包速率控制算法研究

    一.  序 1.1  tcpreplay历史 Tcpreplay 的作者是Aaron Turner,该项目开始于2000年,早期的功能是对tcpdump等抓包工具生成的网络包(即pcap文件)的回放, ...

  5. 在Windows平台下安装与配置Memcached及C#使用方法

    1.在Windows下安装Memcached 资料来源:http://www.jb51.net/article/30334.htm 在Windows平台下安装与配置Memcached的方法,Memca ...

  6. ASP.NET MVC生命周期介绍(转)

    本文以IIS7中asp.net应用程序生命周期为例,介绍了asp.net mvc的生命周期. asp.net应用程序管道处理用户请求时特别强调"时机",对asp.net生命周期的了 ...

  7. MPFIT for python

    MPFIT本来用IDL语言写的,后面有人翻译成了C语言版本.再后面鉴于python语言的流行使用,又有人将其用Cython加了python接口,直接可以在python中调用,极大地方便了额们这些经常用 ...

  8. CentOS7 rc.local开机开法启动

    CentOS 7添加开机启动服务/脚本 一.添加开机自启服务 在CentOS 7中添加开机自启服务非常方便,只需要两条命令(以Jenkins为例):systemctl enable jenkins.s ...

  9. 用iptables做NAT代理,使内网机器上外网

    现状:服务器A只有一个内网IP,不能上外网,内网IP与服务器B内网相通:服务器B有一个内网IP和公网IP.想实现服务器A也能上外网. 1 2 3 4 服务器A:内网网卡:eth0 内网IP:192.1 ...

  10. MySQL数据库分片技术调研

    将这段时间了解的MySQL分片技术和主从复制只是整理清楚画了思维导图记录一下,希望能给需要的人一些帮助 P.S.:个人整理,可能会有错误之处,还望指出~ 要解决的问题 1.海量数据的操作超出单表.单库 ...