android 生命周期

来源:互联网 发布:mysql更改密码 编辑:程序博客网 时间:2024/05/16 05:59

这两天因为一个从后台唤醒导致程序退出的问题困扰了很久。接下来才认真回头来看,android生命周期的详细解释。

生命周期,要说,主要包含的就是:

Application

Activity

在我们的应用程序中,我们通常用来操作的也就是activity。由于它有很多的配置属性,还有intent中的flag。光看网上的介绍,不实际试验一下,真的很难理解其中的参数。


试验1:

A(launchmode=standard,root)->B(standard)->C(standard)

接下来通过home,切换到主屏幕,->home->启动程序图标,这时候显示的C,然后back依次返回退出。

这个时候如果在配置中对A加上(android:clearTaskOnLaunch="true")

home->启动程序图标,则B,C被退出掉,显示A。

home->最近任务切换进入,则还是在C上。


试验2

A(launchmode=singleTask,root)->B(standard)->C(standard)

home->run A 这个时候,BC都会被从栈上清除掉。

home-recent runA 同样的效果

可是如果,A->B的时候,把A finish掉,然后B->C

home->run A ,BC将仍然存在(栈中间已经终端了,A无法清除之前的其他Activity),这个时候backA的话,CB就依次出现了。

试验3

A(launchmode=standard,root)->B(singleTask)->C(standard)

home->run A 这个时候,停留在C,也就是说B的singleTask,不会把C清楚掉。这应该也就是说,singleTask通常要放在根的位置的原因。


试验4,关于程序在后台被系统杀掉后的情况

launchmode=standard 并且堆栈是保持连续的话,home再重新进入,系统会重新创建离开时候的activity。这个时候,往往由于初始化的数据,还未得到正常的初始化,导致报错。因此正确处理的方式是保存推出前的数据,在重新oncreate的时候恢复数据。

launchmode=singetask,点击图标则会重新启动起始的activity,并完成初始化。(这样仍然隐藏一个问题,你仍然可以从最近任务中进入,这样系统还是会去create离开时候的activity)


关于使用FLAG_ACTIVITY_NEW_TASK来跳转一个activity的试验:

在本身程序中,使用这个标识跳转,不会出现新的task。要出现新的task必须设置不同的taskAffinity。

如果同时设置taskAffinity=‘abc’,然后又是singleTask,竟然出现直接无法安装apk的报错。


一些资料:

android:allowTaskReparenting 
    用来标记Activity能否从启动的Task移动到有着affinity的Task(当这个Task进入到前台时)

   “true”,表示能移动,“false”,表示它必须呆在启动时呆在的那个Task里。

    如果这个特性没有被设定,设定到<application>元素上的allowTaskReparenting特性的值会应用到Activity上。默认值为“false”。

    一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着affinity的Task中。典型用法是:把一个应用程序的Activity移到另一个应用程序的主Task中。 
    例如,如果 email中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序定义的,但是,现在它作为email Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当email Task再次进入前台时,就看不到它了。 

    Actvity的affinity是由taskAffinity特性定义的。Task的affinity是通过读取根Activity的affinity决定。因此,根Activity总是位于相同affinity的Task里。由于启动模式为“singleTask”和“singleInstance”的Activity只能位于Task的底部,因此,重新宿主只能限于“standard”和“singleTop”模式。

android:alwaysRetainTaskState 
    用来标记Activity所在的Task的状态是否总是由系统来保持。

    “true”,表示总是;“false”,表示在某种情形下允许系统恢复Task到它的初始化状态。默认值是“false”。

    这个特性只针对Task的根Activity有意义;对其它Activity来说,忽略之。 
    一般来说,特定的情形如当用户从主画面重新选择这个Task时,系统会对这个Task进行清理(从stack中删除位于根Activity之上的所有Activivity)。典型的情况,当用户有一段时间没有访问这个Task时也会这么做,例如30分钟。 
    然而,当这个特性设为“true”时,用户总是能回到这个Task的最新状态,无论他们是如何启动的。这非常有用,例如,像Browser应用程序,这里有很多的状态(例如多个打开的Tab),用户不想丢失这些状态。

android:clearTaskOnLaunch 
    用来标记是否从Task中清除所有的Activity,除了根Activity外(每当从主画面重新启动时)

   “true”,表示总是清除至它的根Activity,“false”表示不。默认值是“false”。

    这个特性只对启动一个新的Task的Activity(根Activity)有意义;对Task中其它的Activity忽略。 
    当这个值为“true”,每次用户重新启动这个Task时,都会进入到它的根Activity中,不管这个Task最后在做些什么,也不管用户是使用BACK还是HOME离开的。当这个值为“false”时,可能会在一些情形下(参考alwaysRetainTaskState特性)清除Task的Activity,但不总是。 
    假设,某人从主画面启动了Activity P,并从那里迁移至Activity Q。接下来用户按下HOME,然后返回Activity P。一般,用户可能见到的是Activity Q,因为它是P的Task中最后工作的内容。然而,如果P设定这个特性为“true”,当用户按下HOME并使这个Task再次进入前台时,其上的所有的Activity(在这里是Q)都将被清除。因此,当返回到这个Task时,用户只能看到P。 
    如果这个特性和allowTaskReparenting都设定为“true”,那些能重新宿主的Activity会移动到共享affinity的Task中;剩下的Activity都将被抛弃,如上所述。

android:finishOnTaskLaunch 
    用来标记当用户再次启动它的Task(在主画面选择这个Task)时已经存在的Activity实例是否要关闭(结束)

   “true”,表示应该关闭,“false”表示不关闭。默认值是“false”。 
    如果这个特性和allowTaskReparenting都设定为“true”,这个特性胜出。Activity的affinity忽略。这个Activity不会重新宿主,但是会销毁。


FLAG_ACTIVITY_NEW_TASK:
       一个Activity一般通过调用startActivity()启动并加入到Task中。它同调用者一样,进入同一个Task。
然而,如果传递给startActivity()的Intent对象中包含FLAG_ACTIVITY_NEW_TASK时,系统会搜索一个新的Task来容纳新的Activity。

       通常,如标志的名字所示,是一个新的Task。然而,并不是必须是。如果已经存在一个Task与新Activity的affinity相同,这个Activity就会加入到那个Task中。如果不是,启动一个新的Task。
       如果启动它的acitve和新Activity的affinity相同,那么新Activity的会进入启动它的acitve所在的Task.