四大组件之Activity(上)——Activity的生命周期、系统回收、系统配置改变的影响

第1节 Activity的使用

Activity几乎是每个应用必有的组件,所以任何安卓应用的开发几乎都是从Activity开始的。

比如,你希望设计一个计算器应用,要呈现这个计算器的功能(显示出计算器的样子,实现计算的能力)一定会在这个应用中创建一个Activity,让这个Activity展示的界面就是计算器。

所以使用Android Studio创建工程以后,会默认为我们创建一个Activity组件,它继承自Android SDK的Activity类。

class CalulatorActivity extends Activity
{
    ......
}

新创建的Activity—CalulatorActivity作为安卓的四大组件之一,一定要在这个应用的配置文件manifest.xml中声明自己的存在,否则系统会不认识这个组件,当你启动它的时候就会报错。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.anddle.calculator">

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name">
        <!--为应用声明一个Activity-->
        <activity android:name=".CalulatorActivity">
        ......
        </activity>
    </application>

</manifest>

第2节 Activity的生命周期

每一个Activity都有它的生命周期,体现了它从诞生到消亡的各个阶段。

下图为我们展示了Activity整个生命的过程,这是安卓官方提供的Activity生命周期图。

2.1 生命各个时期的回调

Activity每进入到一个生命的阶段,就会调用这些状态对应的函数。

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
}

 @Override
protected void onDestroy() {
   super.onDestroy();
}

@Override
protected void onResume() {
   super.onResume();
}

@Override
protected void onPause() {
   super.onPause();
}

@Override
protected void onStart() {
   super.onStart();
}

@Override
protected void onStop() {
   super.onStop();
}

@Override
protected void onRestart() {
   super.onRestart();
}

如果我们在代码中继承了Activity类,并覆盖了这些函数,我们就能感知到Actvity生命状态的转换,并在这个转换的时刻让Activity做对应的处理。

比如在Activity创建的时候,让它调用我们的代码,完成界面的布局;在Activity销毁的时候,让它调用我们的代码,完成界面资源的释放。

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //进行界面的布局
        setContentView(R.layout.activity_main);
        ......
}

 @Override
protected void onDestroy() {
        super.onDestroy();
        //释放一些界面可能占用的资源
        ......
}

2.2 Activity的状态

接下来,我们详细介绍下Acivity的各个阶段。这些阶段都是成对出现的。根据不同的标准,我们将它们分成三类:

  1. 全生命周期:这是Activity的从创建到销毁的整个阶段,从onCreate()开始到onDestroy()结束。
  2. 可见生命周期:这是Activity能被用户看到的整个阶段,这里说的能被看到包括了“虽然被显示但是不能与用户交互”的情况,例如你正在微信聊天,突然系统弹出来一个对话框类型的Activity,提示你电量不足,这时微信界面被挡在后面,不能和用户交互了,但是你还能看到。从onStart()开始到onStop()结束。

  3. 前台生命周期:这是Activity可以和用户进行交互的阶段。从onResume()开始到onPause()结束。

2.3 Acivity常见的切换周期

2.3.1 完全周期

从一个Activity创建出来,到显示,再到用户按返回键主动退出销毁这个Activity,它将经历:

onCreate()->

onStart()->

onResume()->

用户可以与Activity交互,用户按返回键主动退出->

onPause()->

onStop()->

onDestroy()

2.3.2 Activity启动另一个Activity

Activity A创建出来,并显示;然后Activity A启动另一个Activity B,B创建出来,并显示,它将经历:

Activity A onCreate()->

Activity A onStart()->

Activity A onResume()->

用户可以与Activity A交互,然后Activity A启动另一个Activity B,

Activity A onPause()->

Activity B onCreate()->

Activity B onStart()->

Activity B onResume()->

Activity A onSaveInstanceState()->

Activity A onStop()->

Activity A被隐藏,用户可以与Activity B交互;

2.3.3 Activity屏幕旋转

如果一个Activity从创建出来,到显示,然后旋转,那么它将经历:

onCreate()->

onStart()->

onResume()->

用户可以与Activity交互,此时屏幕进行旋转,从竖屏变横屏->

onPause()->

onSaveInstanceState()->

onStop()->

onDestroy()->

onCreate()->

onStart()->

onRestoreInstanceState()->

onResume()->

用户可以与Activity交互;

在周期变化的过程当中,加入了onSaveInstanceState()onRestoreInstanceState()。虽然它们不是Activity周期的一部分,但是对它们对回调在Activity的各种切换扮演了非常重要的角色--提供了保存Activity数据的时机。

第3节 Activity的系统回收

在Activity生命的周期中,安卓系统可能直接回收Activity。系统回收Activity有两种常见的情况,

  1. 系统资源紧张;
  2. 屏幕的旋转;

3.1 资源紧张

当系统资源紧张的时候,例如你打开了很多应用,系统中的可用内存很少了。这是安卓系统会采用一个策略来回收系统中的资源。

  1. 对于那些没有显示或者虽然显示了、但却没有和用户做交互的Activity们,系统会优先回收那些没有显示的Activity(例如在onStop()状态下的Activity);
  2. 如果回收那些资源以后,发现资源还是不够用,就会回收虽然显示了、但却没有和用户做交互的Activity(例如在onPause()状态下的)。

这里会遇到一个问题:假如Activity A启动了Activity B之后,系统发现内存不足,在回收了其它所有资源后,它不得不继续回收Activity A。

3.1.1 产生的问题

此时与Acitity B正在交互的用户,点击了“返回”按钮,按照道理,应该显示Activity A才对,但是系统已经回收了Activity A。这时该怎么办呢?

系统遇到这种情况就会重新创建Activity A,重新调用它的onCreate()。

不过这里又会遇到另一个很现实的问题:如果之前的Activity A上面用户正输入了一些东西,例如他的名字和邮箱地址,或者是已经编辑了很长一大段的文字,如果系统onCreate的话,这些输入的东西就会被清除掉了。这可怎么办呢?

3.1.2 解决办法

安卓系统为我们提供了一个这种情况下数据的重建机制:在Activity被放到后台运行的时候使用onSaveInstanceState()回调函数来保存这些数据,

@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
   super.onSaveInstanceState(savedInstanceState);
   //将要保存的数据,例如撰写的文档的字符串,保存到savedInstanceState变量当中
}

在Activity被重建的时候,使用onRestoreInstanceState()回调函数来恢复这些数据

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
   super.onRestoreInstanceState(savedInstanceState);
   //将需要恢复的数据,例如文档字符串,从savedInstanceState变量中取出,设置到界面上
}

需要注意的是,onSaveInstanceState()onRestoreInstanceState()在Activity周期切换过程中并不一定会被调用,只是在这种Activity异常流程处理时(Activity被系统回收、config信息变化等情况),才会被调用到。

3.2 屏幕旋转

屏幕旋转时,Activity的生命周期也将发生变化。

如果一个Activity从创建出来,到显示,然后旋转,那么它将经历:

onCreate()->

onStart()->

onResume()->

用户可以与Activity交互,此时屏幕进行旋转,从竖屏变横屏->

onPause()->

onSaveInstanceState()->

onStop()->

onDestroy()->

onCreate()->

onStart()->

onRestoreInstanceState()->

onResume()->

用户可以与Activity交互;

可以看到,旋转的时候onCreate()函数会被再次调用。在这里,如果拥有横屏布局文件,onCreate()中的setContentView()将会使用横屏的布局,如果没有,依然使用默认的布局文件。

3.2.1 产生的问题

如果Activity从竖屏变成横屏,那么会先执行onDestroy(),再进行一次onCreate()创建的过程。这意味着之前界面上显示的数据需要重新刷新一次。

假如之前刷新这些数据需要花费很长的时间,那就有必要认真的思考如何避免数据的再次刷新。

3.2.2 解决方法

解决屏幕旋转时Activity被create两次的方法有两种。

  1. onSaveInstanceState()onRestoreInstanceState()可用用来保存和还原这些数据;
  2. AndroidManifest.xml文件中,给这个Activity组件加上android:screenOrientation="orientation|screenSize"的属性就可以了;
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.anddle.anddleplayer">
    
        <application
            ......>
            <activity
                android:name=".VideoListActivity"
                android:configChanges="orientation|screenSize">
            </activity>
            ......
        </application>
    
    </manifest>

    这种Activity从创建出来,到显示,然后旋转,那么它将经历:

    onCreate()->

    onStart()->

    onResume()->

    用户可以与Activity交互,此时屏幕进行旋转,从竖屏变横屏->

    onConfigurationChanged();

    如此一来,这个Activity在旋转时就不会重走销毁、创建的过程了,而只是在旋转后经历一个onConfigurationChanged()。这种情况下,如果存在它对应的横屏布局文件,那么这个布局也不会被使用到,因为onCreate()并没有被调用到。

第4节 系统设置改变

当设备的系统设置发生变化时,例如横竖屏切换、语言变化,可以被Activity感知到。

4.1 监听系统设置改变

系统设置发生变化可以通知到Activity,

  1. AndroidManifest.xml文件当中,给对应的Activity标签,添加android:configChanges属性,例如

    <activity android:name=".AlertActivity"
        <!--指定Activity关注的系统变化类型,这里只表示关注屏幕大小是否变化-screenSize、
            设备方向是否变化-orientation-->
        android:configChanges="screenSize|orientation">
    </activity>
  2. 在需要在实现Activity的代码中做出相应的修改:
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //从newConfig中获取感兴趣的系统配置变化事件,例如屏幕方向是否变化,系统语言是否变化等等
    if(Configuration.ORIENTATION_PORTRAIT ==
            newConfig.orientation) {

    }
}

在manifest中指定关注的是screenSizeorientation,那么当手机从横屏变化成竖屏(或者竖屏变化成横屏)的时候,这个函数就会被调用,就可以在这里添加我们需要的代码。

系统变化的种类很多,除了screenSizeorientation还有:keyboardHidden locale fontScale等等。

4.2 设备旋转

我们可以用两种方法处理设备的旋转,

  1. 让Activity不跟随设备方向的旋转而旋转,它只有竖屏(或只有横屏)的界面。要做到这一点很容易,在AndroidManifest.xml文件中,给这个Activity组件加上android:screenOrientation="portrait"

    (保持竖屏)或者android:screenOrientation="landscape"

    (保持横屏)的属性就可以了;

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.anddle.anddleplayer">
        <application
            ......>
            <activity
                android:name=".VideoListActivity"
                android:screenOrientation="landscape">
            </activity>
            ......
        </application>
    </manifest>
  2. 让Activity跟随设备方向的旋转而旋转。

    采用章节3.2中介绍的方法。

时间: 2024-12-14 14:46:19

四大组件之Activity(上)——Activity的生命周期、系统回收、系统配置改变的影响的相关文章

Activity(活动)生命周期--系统回收活动数据存储

当一个活动进入停止状态的时候,是有可能被系统回收的.那如果处于停止状态的活动被系统回收了,而它上面却有我们所需要数据该如何保存呢?(类似于:打开qq进入下一个界面没有进去,返回的时候仍然不需要你输入账户名和密码)Activity类中提供了onSaveInstanceState()回调方法,这个方法可以保证活动在被回收之前一定会被调用,因此我们可以通过这个方法来解决活动被回收时临时数据得不到保存的问题. onSaveInstanceState()方法会携带一个Bundle类型的参数,Bundle提

Android 四大组件之Service(上)

1.Service简介 Service是Android四大组件中最与Activity相似的组件,他们都代表可执行的程序.Service一直运行于后台,不会与用户交互,可用来处理一些耗时的任务(比如:后台播放音乐,I/O操作等).它的创建.配置与Activity基本相似,下面将详细介绍Android Service的开发. 2.创建.配置Service 2.1 定义一个继承Service类的子类 2.2 在AndroidManifest.xml中配置该Service 需要注意的是 Service和

Activity和Service的生命周期(图)

1.Activity的生命周期 情形一.一个单独的Activity的正常的生命过程是这样 的:onCreate->onStart->onPause->onStop->onDestroy.例如:运行一个 Activity,进行了一些简单操作(不涉及页面的跳转等),然后按返回键结束. 情形二.有两个Activity(a和b),一开始显示a,然后由a启动b,然后在由b回到a,这时候a的生命过程应该是怎么样的呢(a被b完全遮盖)? a经历的过程为 onCreate->onStart-

Activity和Fragment的生命周期

Activity和Fragment的生命周期

Android 四大组件(1)--Activity

四大组件分类 Activity (本文所述) Service   //服务 Content Provider   //内容提供者 BroadcastReceiver   //广播接收器 概括---------------------------------------------------------------------- 在Android 应用程序中,每个Activity通常对应一个可视化界面,其中可以显示Android的各种UI控件,用户可以用来交互为了完成某项任务.Activity中

android四大组件(一)Activity

一.创建一个新的Activity 1.android的四大组件都要在清单文件里面配置 2.如果想让你的应用有多个启动图标,你的activity需要这样配置 <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </inte

Android activity和service的生命周期对比

1Activity生命周期 七个方法 1. void onCreate(Bundle savedInstanceState) 当Activity被第首次加载时执行.我们新启动一个程序的时候其主窗体的onCreate事件就会被执行.如果Activity被销毁后(onDestroy后),再重新加载进Task时,其onCreate事件也会被重新执行. 2. void onStart()   activity变为在屏幕上对用户可见时调用. 3. void onResume()   activity开始与

Activity具体解释(生命周期、以各种方式启动Activity、状态保存,全然退出等)

一.什么是Activity? 简单的说:Activity就是布满整个窗体或者悬浮于其它窗体上的交互界面.在一个应用程序中通常由多个Activity构成,都会在Manifest.xml中指定一个主的Activity,例如以下设置 <actionandroid:name="android.intent.action.MAIN" /> 当程序第一次执行时用户就会看这个Activity,这个Activity能够通过启动其它的Activity进行相关操作.当启动其它的Activity

Activity详细解释(生命周期、以各种方式启动Activity、状态保存,等完全退出)

一.什么是Activity? 简单的说:Activity或者悬浮于其它窗体上的交互界面. 在一个应用程序中通常由多个Activity构成.都会在Manifest.xml中指定一个主的Activity,例如以下设置 <actionandroid:name="android.intent.action.MAIN" /> 当程序第一次执行时用户就会看这个Activity,这个Activity能够通过启动其它的Activity进行相关操作.当启动其它的Activity时这个当前的这