一、Activity状态

  Activity有三种状态:active/running、paused、stopped。

  1、active/running状态,在当前屏幕时,即用户可见的Activity,位于当前Task的栈顶。

  2、paused状态,Activity失去焦点但对用户依然可见。也就是说在它上面有另外一个非全屏或者透明的Activity,并成为了当前的焦点。它还没有被其他的Activity完全遮盖住,而paused的Activity依然是alive状态的,它保留着所有的状态和成员信息并连接至窗口管理器,但当系统处于极低内存的情况下,仍然可以杀死这个Activity。

  3、stopped 状态,当Activity完全被另一个Activity覆盖时,它仍然保留所有的状态和成员信息。但它不再被用户可见,所以它的窗口将被隐藏,当其它地方需要内存,则系统经常会杀死这个Activity。

  当Activity是paused或者stopped状态时,系统可以通过要求它结束(调用它的finish()方法)或直接杀死它的进程来将它驱出内存。当它再次为用户可见的时候,它只能完全重新启动并恢复至以前的状态。

启动并恢复至以前的状态。

二、为什么会有这么麻烦的状态变化

  1、手机屏幕大小有限,只能看到有限的界面数量,用户需要通过Back键或Home键或其他方式切换Activity。

  2、在有手机来电时,系统会优先切换显示电话接听界面。

  由于上述的一些原因,确实存在界面随时可能发生切换的情况,最佳方式当然不是每次都直接销毁之前的界面,很多时候我们也需要在回到之前界面后恢复之前的状态。我们需要了解这些状态,当然还包括要掌握Activity的“生命周期”等知识,这样就能够在Activity发生变化时,知其所以然,并能够根据需求采取一定的措施,例如切换界面时,保存当前的界面信息,即使其被意外杀死也能恢复之前状态。

三、Activity生命周期

  当一个Activity从这个状态转变到另一个状态时,它被以下列protected方法所通知:

public class Activity extends ApplicationContext
{
protected void onCreate(Bundle savedInstanceState); protected void onStart(); protected void onRestart(); protected void onResume(); protected void onPause(); protected void onStop(); protected void onDestroy();
}

  1、onCreate -- 当Activity第一次创建时会被调用(未被销毁前不会被再次调用)。在这个方法中可以做一些初始化工作,例如对创建新的View、获取并设置View的一些属性、绑定列表的数据等等。如果能捕获到Activity 状态的话,这个方法传递进来的Bundle对象将存放了Activity当前的状态。调用该方法后一般会调用onStart()方法。此时Activity不可见,所以并不是所有的初始化工作都适合在这里做,例如一些动画的开始。

  2、onRestart -- 在Activity被停止后重新启动时会调用该方法。其后续会调用onStart方法。

  3、onStart -- 当Activity对于用户可见前即调用这个方法。如果Activity回到前台则接着调用onResume() ,如果Activity隐藏则调用onStop()。此时Activity可能可见,但即使可见,也无法进行交互操作。

  4、onResume -- 在Activity开始与用户交互前调用该方法。在这时该Activity 处于Activity 栈的顶部,并且接受用户的输入。其后续会调用 onPause() 方法。此时Activity也不一定可见,需要通过onWindowFocusChanged(boolean)来确定Activity是否可见。

  5、onPause -- 在系统开始准备恢复其它Activity时会调用该方法。这个方法中通常用来提交一些还没保存的更改到持久数据中,停止一些动画或其它一些耗CPU的操作等等。无论在该方法里面进行任何操作,都需要较快速完成,因为如果它不返回的话,下一个Activity 将无法恢复出来。如果Activity 返回到前台将会调用onResume(),如果Activity变得对用户不可见了将会调用onStop() 。

  6、onStop -- 在Activity对用户不可见时将调用该方法。可能会因为当前Activity 正在被销毁,或另一个Activity(已经存在的Activity 或新的Activity )已经恢复了正准备覆盖它,而调用该方法。如果Activity 正准备返回与用户交互时后续会调用onRestart ,如果Activity正在被释放则会调用onDestroy 。

  7、onDestroy -- 在Activity被销毁前会调用该方法。这是Activity能接收到的最后一个调用。可能会因为有人调用了finish方法使得当前Activity正在关闭,或系统为了保护内存临时释放这个Activity的实例,而调用该方法。你可以用isFinishing方法来区分这两种不同的情况。

  要注意的是,onPause(),onStop(),onDestory()这3个方法都可能会因为系统内存不足而被系统直接kill。而平常从一个Activity转向/回到另一个Activity时,当新Activity是full screen(弹出窗口,例如AlertDialog是不算的)的时候就会调用前一个Activity的onPause(),然后调用onStop(),而无论onPause或者onStop,都有可能被kill,所以一般在onPause时就应该保存需要持久化的一些数据(例如用户编辑的信息)。

  onCreate、onStart、onResume都不是Activity准确能够交互的点,真正的是onWindowFocusChaned()函数被执行时。

四、Android的进程

  android根据其重要性在内存不足的时候移去重要性最低的进程。重要性由高到低为:

  1、活动/前台进程

    指那些有组件正和用户进行交互的应用程序进程。他们都是android尝试通过回收资源来使其保持响应的进程。这些进程的数量非常少,只用到最后的关头才会终止这些进

程。

    活动进程包括:

      处于“活动”状态的Activity,也就是说,它们位于前台并对用户事件进行响应。
      正在执行onReceive事件处理程序的广播接收器。
      正在执行onCreate()、onStart()或onDestory事件处理程序的服务。
      正在运行,且已被标记为前台运行的服务。
  2、可见进程
    可见,但是非活动的进程是指那些驻留可见活动的进程。顾名思义,可见的活动能被用户看到,但是他们并不是在前台运行或者能对用户事件做出响应,比如,当一个活动Activity被部分遮挡的时候(被一个非全屏或者半透明状态的Activity遮挡时)就会出现这类情况。这类进程的数量很少,只有在资源极度缺乏的环境下,为保证活动进程的继续执行,才会终止这些进程。

  3、服务进程

    已经启动的服务进程。服务支持在没有可见界面的情况下,仍然能继续不间断地进行处理。因为后台服务没有直接和用户进行交互,所以它们的优先级要比可见进程低一些。但是他们仍然被认为是前台进程。除非活动或者可见进程需要资源,否则不会终止它们。

  4、后台进程
        不可见,并且没有任何正在运行的服务的活动的进程,通常会有大量的后台进程。这样的程序拥有一个用户不可见的Activity。这样的程序在系统内存不足时,按照LRU的顺序被结束。

    运行着一个对用户不可见的Activity(调用过onStop() 方法)。这些进程对用户体验没有直接的影响,可以在服务进程、可见进程、前台进程需要内存的时候回收。通常,系统中会有很多不可见进程在运行,他们被保存在LRU (least recently used) 列表中,以便内存不足的时候被第一时间回收。如果一个Activity正确的执行了它的生命周期,关闭这个进程对于用户体验没有太大的影响。
  5、空进程
    这样的进程不包含任何活动的程序部件。系统可能随时关闭这类进程。未运行任何程序组件。运行这些进程的唯一原因是作为一个缓存,缩短下次程序需要重新使用的启动时间。系统经常中止这些进程,这样可以调节程序缓存和系统缓存的平衡。

  Android对进程的重要性评级的时候,选取它最高的级别。另外,当被另外的一个进程依赖的时候,某个进程的级别可能会增高。一个为其他进程服务的进程永远不会比被服务的进程重要级低。因为服务进程比后台Activity进程重要级高,因此一个要进行耗时工作的Activity最好启动一个Service来做这个工作,而不是开启一个子进程――特别是这个操作需要的时间比Activity存在的时间还要长的时候。例如,在后台播放音乐,向网上上传摄像头拍到的图片,使用Service可以使进程最少获取到“服务进程”级别的重要级,而不用考虑Activity目前是什么状态。broadcast receivers做费时的工作的时候,也应该启用一个服务而不是开一个线程。

五、Activity状态的保存

protected void onSaveInstanceState (Bundle outState)
protected void onRestoreInstanceState (Bundle savedInstanceState)

  onSaveInstanceState() 和 onRestoreInstanceState() 并不是生命周期方法。它们并不是总会被调用。例如通过Back造成的销毁Activity时,它就不会被调用。应该只用它来为Activity保存一些临时的状态,而不能用来保存持久性的数据。而是应该用onPause()来达到这个目的。

  onPause()方法是在系统结束应用程序前调用的最后一个安全的方法。无法保证onStop和onDestroy会被调用,所以不能依赖这两个方法来实现关键逻辑。

六、Activity的加载模式

  Activity加载模式(通过在AndroidManifest.xml文件中activity元素的android:launcherMode属性设置) 。请参考文章结尾附带的demo体验Activity的加载模式。

  1、standard(默认)
    测试方式:MainActivity(standard),SecondActivity(standard)
    每次都是创建了新的Activity实例。

  2、singleTop
    测试方式:MainActivity(singTop),MainActivity自己intent自己
    测试方式:MainActivity(singleTop),SecondActivity(standard)
    和standard一样是发送新的实例,但singleTop要求如果创建intent的时候栈顶已经有要创建的Activity实例,则将intent发送给该实例。例如给MainActivity设置singleTop,然后按钮也是intent自己,那么会发现一直都是MainActivity当前这个实例,因为他一直在栈顶,所以不会创建新的。

    如果用A打开B,而B再打开A,如此循环,如果A是设置了singleTop,B是默认,则每次A都是新的,因为每次要打开A时,栈顶都不是A,就要创建新的A实例(和都是 standard没啥区别了)。
    此种模式的应用场景,目前想到就是为了解决自己在栈顶时,自己给自己发送intent可以不创建新的实例。实际中应用的也较少。

  3、singleTask
    测试方式:MainActivity(singleTask),SecondActivity(standard)
    只创建一个实例。如果发现有对应的Activity实例,则是此Activity实例之上的其他Activity实例全部出栈,使此Activity实例成为栈顶对象,显示出来。
  4、singleInstance
    这个模式下的Activity单独在一个task栈中。这个栈只有一个Activity。目的是为了多个Task共享一个Activity。

七、Activity与View的生命周期

  View和Activity一样也有自己的生命周期,具体在View的周期中包含哪些通知函数,参见http://developer.android.com/reference/android/view/View.html。其中onMeasure、onLayout、onDraw最重要,而onMeasure最难理解(之后会单独讨论这个函数及其如何使用)。

八、Activity的注意事项

  1、onConfigurationChanged

    1)不设置Activity的android:configChanges时,屏幕切屏会导致当前Activity被销毁并重新创建。

    2)设置Activity的android:configChanges=“orientation”时,在3.2以前的版本会阻止系统默认的行为,即销毁并重新创建当前Activity。而3.2+的需要另外加上screenSize。
    3)而实际运行中还会有很多系统的配置改变导致Activity被销毁并重新创建,例如键盘模式、全局字体大小发生改变等等(具体有哪些参见http://developer.android.com/guide/topics/manifest/activity-element.html),对于这些配置的改变,不应该盲目使用configChanges配置拦截,理应根据实际需求来决定是否拦截及处理。

    4)当使用onConfigurationChanged自行处理时,必须调用super.onConfigurationChanged(newConfig),不能删除,否则会报调用异常错误。

九、参考文章

  http://blog.csdn.net/liuhe688/article/details/6754323

  http://marshal.easymorse.com/archives/2950

  android:configChanges  

  http://blog.csdn.net/imdxt1986/article/details/7339711

  http://blog.csdn.net/huiguixian/article/details/8071821

  http://bbs.csdn.net/topics/390413976

Activity加载模式测试DEMO

Activity相关知识点总结的更多相关文章

  1. Android开发涉及有点概念&相关知识点(待写)

    前言,承接之前的 IOS开发涉及有点概念&相关知识点,这次归纳的是Android开发相关,好废话不说了.. 先声明下,Android开发涉及概念比IOS杂很多,可能有很多都题不到的.. 首先由 ...

  2. IOS开发涉及有点概念&相关知识点

    前言,IOS是基于UNIX的,用C/C+/OC直通系统底层,不想android有个jvm. 首先还是系统架构的分层架构 1.核心操作系统层 Core OS,就是内存管理.文件系统.电源管理等 2.核心 ...

  3. UITableView相关知识点

    //*****UITableView相关知识点*****// 1 #import "ViewController.h" // step1 要实现UITableViewDataSou ...

  4. IOS之UI--小实例项目--添加商品和商品名(使用xib文件终结版) + xib相关知识点总结

    添加商品和商品名小项目(使用xib文件终结版) 小贴士:博文末尾有项目源码在百度云备份的下载链接. xib相关知识点总结 01-基本使用 一开始使用xib的时候,如果要使用自定义view的代码,就需要 ...

  5. 学习记录013-NFS相关知识点

    一.NFS相关知识点 1.NFS常用的路径/etc/exports NFS服务主配置文件,配置NFS具体共享服务的地点/usr/sbin/exportfs NFS服务的管理命令,exportfs -a ...

  6. TCP/IP 相关知识点与面试题集

    第一部分:TCP/IP相关知识点 对TCP/IP的整体认 链路层知识点 IP层知识点 运输层知识点 应用层知识点 (这些知识点都可以参考:http://www.cnblogs.com/newwy/p/ ...

  7. Python开发一个csv比较功能相关知识点汇总及demo

    Python 2.7 csv.reader(csvfile, dialect='excel', **fmtparams)的一个坑:csvfile被csv.reader生成的iterator,在遍历每二 ...

  8. Caffe学习系列(二)Caffe代码结构梳理,及相关知识点归纳

    前言: 通过检索论文.书籍.博客,继续学习Caffe,千里之行始于足下,继续努力.将自己学到的一些东西记录下来,方便日后的整理. 正文: 1.代码结构梳理 在终端下运行如下命令,可以查看caffe代码 ...

  9. php正则相关知识点

    关于正则,其实简单就是搜索和匹配.php,java,python等都是支持正则的,php正则兼容perl.好多同学觉得正则比较难,比较抽象,其实正则是非常简单的,主要是一个熟悉和反复练习的结果,还有一 ...

随机推荐

  1. poj 1523 SPF(双连通分量割点模板)

    题目链接:http://poj.org/problem?id=1523 题意:给出无向图的若干条边,求割点以及各个删掉其中一个割点后将图分为几块. 题目分析:割点用tarjan算法求出来,对于每个割点 ...

  2. Linux/Unix系统编程手册 第三章:系统编程概念

    本章介绍系统编程的基础概念和一些后续章节用到的函数及头文件,并说明了可移植性问题. 系统调用是受控的内核入口,通过系统调用,进程可以请求内核以自己的名义去执行某些动作,比如创建子进程,执行I/O操作, ...

  3. C#:system.collections.generic(泛型)

    1. array是一个固定长度的,如果要动态的存储的话就不行了,虽然 System.Collections.ArrayList(),是一个动态的存储的容器,但是没有对存储中的数据进行一个约束,所以非泛 ...

  4. System Board Replacement Notice

    System Board Replacement Notice System Board Replacement Notice for TP 770E and TP 600 Restoring the ...

  5. H5页面遮罩弹框下层还能滚动的问题

    在页面上显示一个遮罩层,这是非常常见的操作,在遮罩层上操作,下层也会默认跟随手指滚动 此处就是要在显示遮罩的时候禁止下层滚动. 首先设置一个全局变量 var canScroll=false; 页面初始 ...

  6. 51nod 1563 坐标轴上的最大团(今日gg模拟第一题) | 线段覆盖 贪心 思维题

    51nod 1563 坐标轴上的最大团 坐标轴上有n个点,每个点有一个权值.第i个点的坐标是 xi ,权值是 wi .现在对这些点建图.对于点对 (i,j) ,如果 |xi−xj|≥wi+wj ,那么 ...

  7. 【spoj NSUBSTR】 Substrings

    http://www.spoj.com/problems/NSUBSTR/ (题目链接) 题意 给出一个字符串S,令${F(x)}$表示S的所有长度为x的子串出现次数的最大值.求${F(1)..... ...

  8. 第一章:CDib类库的建立

    VC++图像处理程序设计(第1版)    杨淑莹 编著     边奠英 主审 第一章 位图基础 Joanna-In-Hdu&Hust 手工打,印象更深刻 使用工具 VS2010 mfc  整本 ...

  9. 前端学习 -- image标签和meta标签

    Image标签 使用img标签来向网页中引入一个外部图片, img标签也是一个自结束标签 属性: src:设置一个外部图片的路径 alt:可以用来设置在图片不能显示时,对图片的描述 搜索引擎可以通过a ...

  10. svn提交失败 :“svn: E200007: Commit failed”

    引言: 在切换subversion服务器地址之后,发生的无法正确提交代码的问题org.apache.subversion.javahl.ClientException: svn: E200007: C ...