1. 基本介绍

大家平时只要懂一点Android知识的话,都一定会知道,一个应用的组成,往往包含了许多的activity组件,每个activity都应该围绕用户的特定动作进行跳转设计。比如说,一个电话通讯录的应用可能有一个总体展示电话录上所有存储的姓名的activity,当用户选择指定的姓名时,可以启动另一个新的activity用来展示选中此姓名的详细内容。当然,一个activity也可以用来打开同一台手机但存在在其它应用的activity,比如,你的应用想要发送一份邮件时,可以定义一个intent来执行一个"send"动作并包含一个数据(地址和信息),另一个应用中此时有一个刚好可以处理这种intent的activity就会被打开(如果有多个activity支持同样的intent,那么系统就会让用户自行选择一个)。当email被发送后,你的activity被恢复并且看起来发送邮件的activity好像是你应用的一部分。即使两个activity来自不同的应用,Android系统也能将两个activity保存在同一个任务中来实现这种无缝隙的用户体验。这里,我们就引出了一个概念,究竟何为Android中的任务Tasks?它与启动模式又有什么关系?所谓的Back Stack又是什么?在本篇中,我主要分享一下Tasks与Back Stack的基本介绍,为之后介绍android的启动模式做一下铺垫。当然,若你想详细了解此内容,也可以访问官方文档:Task and Back Stack

2. Tasks与Back Stack

一般说来,Tasks是我们在执行某种工作时所交互的activity的集合,这些activity集合按照打开的顺序被放置在同一个栈中,这个栈叫作Back Stack(我称为后退栈)。当我们点击到launcher上的图标时,这个图标对应的应用的task则会被置换到前台。若这个应用不存在task,也说明没有打开过或者打开过但被销毁了,那么就会为这个应用创建一个新的task,此时这个应用的MainActivity则会被创建,然后作为根Activity被压入到这个task中。

当当前的Activity启动了另外一个activity之后,新的activity就会被压入栈顶,并拥有焦点。之前的activity仍然保存在栈中,但是状态是停止的。当activity处于栈中的时候,系统会保留当前界面的状态,当用户按下back键时,当前就activity就会从stack中弹出销毁,之前的一个activity就会从保存的状态中恢复。在栈中的顺序不能被重新安排,只允许在栈上执行压入和弹出。当创建新的activity的时候,压入栈中;当按下后退键的时候,弹出栈中。因此,后退栈是一个“后进先出”的结构体。如下图:

当然,如果我们不停的按后退键,栈中的activity会不停的被弹出,直到回到home界面(或者回到创建task的正在运行的activity)。当所有的activity都从栈中移除之后,这个task就被销毁了。

task可以被整体移到后台,当用户启动了一个新的task,或者按下了home按钮。后台task中的所有activity的状态都是停止的,task的stack中的内容被保存下来,只是task失去了焦点。

我们需要注意的是:后台可以保持多个Task同时存在,但是,若在同一时刻后台运行了太多的Task,这时系统要能会销毁后台的Activity,以用来回收内存,这会导致activity状态的丢失。

3. 保存Activity的状态

按照前面所说的,当Activity停止时(Stopped)时,系统默认会保存其状态。当我们通过back键回到这个Activity时就会恢复离开时候的界面。当然,当多个Tasks同时保存在后台时,系统也有可能会销毁后台的activity,以回收内存。在这种情况下,系统仍然会知道Activity在task中的位置,当通过back键回到这个Activity时,系统会重新创建(recreate)一个Activity,而不是像之前一样恢复(resume)它,因此,为了不丢失Activity的内容,我们可以通过实现onSaveInstanceState()方法来主动保存数据。

4. 总结

通过上面对Task与back stack的学习,相信对于一些概念有了更加清楚的认识,现在我们可以总结一下:

  • activity A 启动activity B,activity A 停止,但是系统还是保留着它的状态。当用户在activity B上按下后退按键,activity A会从保留的状态中的恢复运行。

  • 当用户按下home键后离开一个task,这个task的当前activity停止,整个task进入到后台。系统保留着stack中的每一个activity的状态。如果用户点击launcher上的task图标,这个task就会被重新放到前台,task的栈顶activity也会恢复运行。

  • 当用户按下后退按钮,栈顶的activity就会从栈中弹出销毁,之前的activity就会恢复运行。activity被销毁后,系统不会保持它的状态。

  • 有的activity可以被实例化多次,甚至是从不同的task。

  • 当后台中有同时存在多个Task时,系统可能会销毁保存在后台的activity以回收内存,为了不丢失activity中内容,我们可通过onSaveInstanceState()方法保存数据。

Android系统管理Task,是通过将所有的activity按照启动的顺序压入到一个Task中,若一个Activity被启动多次,会默认创建它的多个实例,然后将新的实例压入。当然,我们也可以打破这种默认的行为。可能你想在你应用的activity启动时开始一个新的任务(而不是放置到当前栈中);或者,当你启动一个activity,你想把已经运行的它的一个实例提到前台来(而不是创建一个新的实例放在后退栈的顶端);或者,你希望当用户离开任务时,你的后退栈清除除了根activity以外所有的activity。对于这些行为,我们该如何进行设置?

好了,今天的分享就到这里,接下来我会针对上面的问题分享Android的启动模式,希望大家持续关注!

Android的启动模式(上)的更多相关文章

  1. Android Activity 启动模式详解

    最近有群里的朋友问我 Activity的四种启动模式分别是什么意思? 当初因为项目比较忙,草草的解释了下, Api文档中说的也只是一般,在这里就小记一下吧,以便有更多的朋友对Activity启动模式了 ...

  2. Android的启动模式(下)

    Android中的启动模式(下) 在这篇文章中,我会继续跟大家分享有关于Android中启动模式的相关知识.当然,如果对这个启动模式还不完全了解或者没有听过的话,可以先看看我之前写的有关于这个知识点的 ...

  3. Android的启动模式

    启动模式简单地说就是Activity启动时的策略,在AndroidManifest.xml中的<Activity>标签的android:launchMode属性设置: 启动模式有4种,分别 ...

  4. 详解Android Activity启动模式

    相关的基本概念: 1.任务栈(Task)   若干个Activity的集合的栈表示一个Task.   栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...

  5. android:Activity启动模式之singleTask(一)

    先看一下standard启动模式的说明: 仅仅有一个实例.在同一个应用程序中启动他的时候.若不存在此Activity实例.则会在当前栈顶创建一个新的实例.若存在,则会把栈中在其上的其他Activity ...

  6. Android Activity 启动模式和任务栈

    在了解了基本的Activity的生命周期后,我们能够很好的在一个Activity上面做相关的业务.但是这是不够的,因为Android通过任务栈来保存整个APP的Activity,合理的调度任务栈才能够 ...

  7. Android Activity启动模式

    <activity android:name=".MainActivity" android:launchMode="singleTask"> &l ...

  8. AndroidのActivity启动模式

    Activity启动模式      .概念      Activity启动模式定义了Activity启动的规则,它决定着Activity的实例创建与重用与否    .属性     Activity的启 ...

  9. Android活动启动模式

    在android中,android活动是以栈的方式进行存储,在栈中的活动不断被重新激活至前台和不断被终止也不断被排序.因此对于栈中的活动管理也是一个比较麻烦的事情. android给我们提供了两类活动 ...

随机推荐

  1. [ios]离屏渲染优化

    原文链接:https://mp.weixin.qq.com/s?__biz=MjM5NTIyNTUyMQ==&mid=2709544818&idx=1&sn=62d0d2e9a ...

  2. js正则匹配

    var account = $('input[name="account"').val(); var re = /^[0-9]+.?[0-9]*$/; if (!re.test(a ...

  3. 杭电1020-Encoding

    Problem Description Given a string containing only 'A' - 'Z', we could encode it using the following ...

  4. c#线程创建

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. hdu4933 Miaomiao's Function

    水水的计数题,关键在细节. import java.math.BigInteger; import java.util.Scanner; import java.io.*; public class ...

  6. Wireless Network

    Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 19626 Accepted: 8234 De ...

  7. 基本的MFC多线程

    多线程程序我本来是能够来写的.但是由于在图像处理的过程中,对于这方面知识使用的比较少,造成重复忘记的情况.这里再次进行整理学习,特别注重和“图像处理”理清关系,为下一步使用奠定基础. 这里实现的是工作 ...

  8. 炮(cannon)

    炮(cannon)[题目描述] 众所周知,双炮叠叠将是中国象棋中很厉害的一招必杀技.炮吃子时必须隔一个棋子跳吃,即俗称“炮打隔子”. 炮跟炮显然不能在一起打起来,于是rly一天借来了许多许多的炮在棋盘 ...

  9. PHP计划任务之关闭浏览器后仍然继续执行的函数

    函数名称:ignore_user_abort 本函数配置或取得使用端连接中断后,PHP 程序是否仍继续执行.默认值为中断连接后就停止执行.在 PHP 配置文件中 (php3.ini/php.ini) ...

  10. OS: 剪裁UIImage部分不规则区域

    首先,我们需要把图片展示在界面上.很简单的操作,唯一需要注意的是由于CGContextDrawImage会使用Quartz内以左下角为(0,0)点的坐标系,所以需要使用CGContextTransla ...