Activity生命周期

来源:互联网 发布:疯狂联盟座龙升级数据 编辑:程序博客网 时间:2024/06/05 12:07

Activity生命周期

一、任务栈

  1. 概念:
    任务其实就是activity 的栈它由一个或多个Activity组成的共同完成一个完整的用户体验, 换句话说任务就是“应用程序” 。可以为一个应用的各个activity,也可能为多个应用的activity组成一个任务栈。
  2. 原则:
    先进后出规则。总是从栈顶放入或取出activity对象。
  3. 举例:
      假设你想让用户看到某个地方的街道地图。而已经存在一个具有此功能的activity 了,那么你的activity 所需要做的工作就是把请求信息放到一个Intent 对象里面,并把它传递给startActivity()。于是地图浏览器就会显示那个地图。
      而当用户按下BACK 键的时候,你的activity 又会再一次的显示在屏幕上,此时任务是由2个应用程序中的相关activity组成的。
      栈底的是启动整个任务的Activity,栈顶的是当前运行的用户可以交互的Activity,当一个activity 启动另外一个的时候,新的activity 就被压入栈,并成为当前运行的activity。而前一个activity 仍保持在栈之中。当用户按下BACK 键的时候,当前activity 出栈,而前一个恢复为当前运行的activity。栈中保存的其实是对象,栈中的Activity 永远不会重排,只会压入或弹出,所以如果发生了诸如需要多个地图浏览器的情况,就会使得一个任务中出现多个同一Activity 子类的实例同时存在。
      任务中的所有activity 是作为一个整体进行移动的。整个的任务(即activity 栈)可以移到前台,或退至后台。举个例子说,比如当前任务在栈中存有四个activity──三个在当前activity 之下。当用户按下HOME 键的时候,回到了应用程序加载器,然后选择了一个新的应用程序(也就是一个新任务)。则当前任务遁入后台,而新任务的根activity 显示出来。然后,过了一小会儿,用户再次回到了应用程序加载器而又选择了前一个应用程序(上一个任务)。于是那个任务,带着它栈中所有的四个activity,再一次的到了前台。当用户按下BACK 键的时候,屏幕不会显示出用户刚才离开的activity(上一个任务的根activity)。取而代之,当前任务的栈中最上面的activity 被弹出,而同一任务中的上一个activity 显示了出来。

  4. 生命周期引入原由:
      Android系统是一个多任务(Multi-Task)的操作系统,可以在用手机听音乐的同时,也执行其他多个程序。每多执行一个应用程序,就会多耗费一些系统内存,当同时执行的程序过多,或是关闭的程序没有正确释放掉内存,系统就会觉得越来越慢,甚至不稳定。
    为了解决这个问题, Android 引入了一个新的机制– 生命周期(Life Cycle)。
    Android 应用程序的生命周期是由Android 框架进行管理,而不是由应用程序直接控
    制。通常,每一个应用程序(入口一般会是一个Activity 的onCreate 方法),都会产生
    一个进程(Process)。当系统内存即将不足的时候,会依照优先级自动进行进程(process)的回收。不管是使用者或开发者, 都无法确定的应用程序何时会被回收。所以为了很好的防止数据丢失和其他问题,了解生命周期很重要。

二、activity的四种状态

  1. active(running)状态:
      当Activity运行在屏幕前台(处于当前任务活动栈的最上面),此时它获取了焦点能响应用户的操作,属于运行状态,同一个时刻只会有一个Activity 处于活动(Active)或运行

  2. paused状态
      当Activity失去焦点但仍对用户可见(如在它之上有另一个透明的Activity或Toast、AlertDialog等弹出窗口时)它处于暂停状态。暂停的Activity仍然是存活状态(它保留着所有的状态和成员信息并保持和窗口管理器的连接),但是当系统内存极小时可以被系统杀掉。

  3. stopped状态
      它仍然保持着所有的状态和成员的信息,可是,他对于用户来说不可见,当别的地方需要内存的时候它经常会被killed。

  4. dead状态
      Activity 尚未被启动、已经被手动终止,或已经被系统回收时处于非活动的状态,要手动终止Activity,可以在程序中调用”finish”方法。

三、activity生命周期

  1. 生命周期转换调用图
    生命周期转换调用图

2.切换actvity流程图
跳转

回归

四、activity7个方法

方法 描述 调用后是否被杀 下一步操作 onCreate() 当Activity第一次被创建时调用。此处可以做所有的一般静态设置,比如创建视图,绑定列表数据等。如果状态被捕捉,并且此状态存在的话,这个方法传递一个包含这个Activity的前状态的Bundle对象。 否 onStart() onRestart() Activity被停止后,再次启动之前调用。 否 onStart() onStart() 在Activity对用户可见之前被调用。如果这个Activity来到前台,那么下一步操作是调用OnResume()。如果被隐藏,则下一步操作是调用onStop()。 否 onResume()或者onStop() onResume() 在Activity开始与用户交互之前被调用。在这里,该Activity位于Activity栈顶,开始与用户交互。需要注意的是,此时当前Activity处于resumed状态,这个状态下Activity是可见的。 否 onPause() onPause() 当系统正在恢复另一个Activity的时候被调用。这个方法通常用于提交未保存的数据,停止动画以及可能 消耗CPU的事情等。这些应该高效地完成,因为下一个Activity在这个方法没有返回之前不会被运行。如果Activity回到前台,则下一步操作为调用onResume()。如果Activity变得不可见,则调用onStop()。 是 onResume()或者onStop() onStop() 当Activity对用户不再可见的时候调用。这会发生,是因为它正在被销毁或者另一个Activity(可以是已经存在的或者新的)被运行并且覆盖了它。如果Activity恢复与用户交互,则下一步操作是调用onRestart(),如果这个Activity消失,则调用onDestory() 是 onRestart()或者onDestory() onDestory() 该Activity被销毁之前调用。这个Activity收到的最终调用。它可以是因为Activity正在结束(调用finish()),或者是因为系统为保护空间而面临销毁这个Activity的实例而调用。可以通过isFinishing()方法区分这两种情况。 是 无

注意:
  当系统启动另外一个新的Activity时,在新Activity启动之前被系统调用保存现有的Activity中的持久数据、停止动画等,这个实现方法必须非常快。当系统而不是用户自己出于回收内存时,关闭了activity 之后。用户会期望当他再次回到这个activity 的时候,它仍保持着上次离开时的样子。此时用到了onSaveInstanceState(),方法onSaveInstanceState()用来保存Activity被杀之前的状态,在onPause()之前被触发,当系统为了节省内存销毁了Activity(用户本不想销毁)时就需要重写这个方法了,当此Activity再次被实例化时会通过onCreate(Bundle savedInstanceState)将已经保存的临时状态数据传入因为onSaveInstanceState()方法不总是被调用,触发条件为(按下HOME键,按下电源按键关闭屏幕,横竖屏切换情况下),你应该仅重写onSaveInstanceState()来记录activity的临时状态,而不是持久的数据。应该使用onPause()来存储持久数据。
onFreeze()早期为了保存用户数据设置的一种方法,在onPause()之前调用。

五、activity三个嵌套循环

  1. Activity完整的生命周期:
    从第一次调用onCreate()开始直到调用onDestroy()结束
  2. Activity的可视生命周期:
    从调用onStart()到相应的调用onStop()
    在这两个方法之间,可以保持显示Activity所需要的资源。
    如在onStart()中注册一个广播接收者监听影响你的UI的改变,在onStop() 中注销。
  3. Activity的前台生命周期:从调用onResume()到相应的调用onPause()。

六、举例以及activity四种退出方式

1. A启动B,back返回A分两种
(1)B为半透明或者透明或者是个局部activity总之不能完全遮挡A。调用流程如下:
A:onPause()–>B:onCreate()–>B:onStart()–>B:onResume()
按下back:
B:onPause()–>A:onResume()–>B:onStop()–>B:onDetory()(B被出栈)
(2)B完全遮挡A
A:onPause()–>B:onCreate()–>B:onStart()–>B:onResume()–>A:onStop()
按下back:
B:onPause()–>A:onRestart()–>A:onStart()–>A:onResume()–>B:onStop()–>B:onDestory()
2. finish()调用
(1)当前activity A所在task,还有其他activity(B)
则finish过程
A:onPause()–>B:onRestart()–>B:onStart()–>B:onResume()–>A:onStop()–>A:onDestory()
(1)当期activity A所在task中只有它自己了。
则finish()过程:
A:onPause()–>A:onStop()–>A:onDestory()
注意:finish函数仅仅把当前Activity退出了,但是并没有释放他的资源。安卓系统回收机制自己决定何时从内存中释放应用程序(即不会调用onDestory()只是调用了onStop())。当系统没有可用内存到时候,会按照优先级,释放部分应用。所以建议一些业务逻辑最好不要写在onDestory()方法中,可以写到比如onPause()方法中。

3. System.exit(0)
该方法与android.os.Process.killProcess(android.os.Process.myPid())等效
测试效果如下:
调用后确实会结束当前task不过如果当前task只有一个acticity就不调用onPause()–>onStop()–>onDestory()直接结束task.
当task中存在不止一个activity时:当前task也是直接结束,但会生成一个新的task,task中存放下个activity实例。具体见下图:先启动A再从A启动B然后B调用system.exit():
这里写图片描述

注意进程ID的变化直接结束当前task不会调用activity的生命周期方法。而是直接黑屏就跟启动一个新应用差不多有个黑屏时间,因为开启了一个新线程,然后创建最近的activitys实例。

7、APP完全退出的解决方案

转自:Android退出应用程序终极方法

首先,我们将管理Activity的功能通过一个扩展的Application类来实现。

public class MyApplication extends Application {    private static Stack<Activity> activityStack;    private static MyApplication singleton;    @Override    public void onCreate()    {        super.onCreate();        singleton=this;    }    // Returns the application instance    public static MyApplication getInstance() {        return singleton;    }    /**     * add Activity 添加Activity到栈     */    public void addActivity(Activity activity){        if(activityStack ==null){            activityStack =new Stack<Activity>();        }        activityStack.add(activity);    }    /**     * get current Activity 获取当前Activity(栈中最后一个压入的)     */    public Activity currentActivity() {        Activity activity = activityStack.lastElement();        return activity;    }    /**     * 结束当前Activity(栈中最后一个压入的)     */    public void finishActivity() {        Activity activity = activityStack.lastElement();        finishActivity(activity);    }    /**     * 结束指定的Activity     */    public void finishActivity(Activity activity) {        if (activity != null) {            activityStack.remove(activity);            activity.finish();            activity = null;        }    }    /**     * 结束指定类名的Activity     */    public void finishActivity(Class<?> cls) {        for (Activity activity : activityStack) {            if (activity.getClass().equals(cls)) {                finishActivity(activity);            }        }    }    /**     * 结束所有Activity     */    public void finishAllActivity() {        for (int i = 0, size = activityStack.size(); i < size; i++) {            if (null != activityStack.get(i)) {                activityStack.get(i).finish();            }        }        activityStack.clear();    }    /**     * 退出应用程序     */    public void AppExit() {        try {            finishAllActivity();        } catch (Exception e) {        }    }}

注意,为了在我们自己的应用程序中使用这个自定义的Application类,而不是默认的Application类。需要在Manifest文件中修改一下的属性( android:name)。

<application    android:icon="@drawable/icon"    android:label="@string/app_name"    android:name="your_package_name_here.MyApplication">

使用方法:

方法1: 之后我们在所有的activity的oncreate方法中通过getinstance得到一个MyApplication的实例,然后调用addActivity方法把当前的activity加入到stack中,如果要退出应用程序只需要调用AppExit方法即可。

方法2: 自定义一个继承Activity类的BaseActivity

public class BaseActivity extends Activity{    @Override    protected void onCreate(Bundle savedInstanceState){        super.onCreate(savedInstanceState);        //添加Activity到堆栈        MyApplication.getInstance().addActivity(this);    }    @Override    protected void onDestroy(){        super.onDestroy();        //结束Activity&从栈中移除该Activity        MyApplication.getInstance().finishActivity(this);    }}

后续的Activity 都继承这个BaseActivity就可以了。

Android的官方文档中写到”没有必要自定义Application类”
  但事实上,通过逆向工程国际大厂的Android应用,我发现各厂都自定义了Application类用以实现Global变量操作和Activity管理。所以我们也学习一下吧~(你也有兴趣通过逆向工程来借鉴一下别人的Android应用?别急,后续的教程里会陆续介绍的。)以上的代码只是基本的Activity管理方案,以此为框架,我们可以加入更多关于Acitivity的管理方法以及其他全局变量的操作。

0 0