【Android基础】探究Activity

一、Activity的生命周期

1、Activity的状态

每个Activity在其生命周期中最多可能会有4种状态。

1)运行状态

当一个活动位于栈顶时,这时活动就处于运行状态。

2)暂停状态

当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态。

3)停止状态

当一个活动不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。

4)销毁状态

当一个活动从返回栈中移除后就变成了销毁状态。

2、Activity的生命周期示意图

在这里插入图片描述

  • onCreate():
    在Activity第一次被创建的时候调用。一般在这个方法中完成Activity的初始化操作。
  • onStart():
    在Activity由不可见变为可见的时候调用。
  • onRestart():
    在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。
  • onResume():
    在Activity准备好和用户进行交互的时候调用。
  • onPause():
    在系统准备去启动或者恢复另一个Activity的时候调用。
  • onStop():
    在Activity完全不可见的时候调用。
  • onDestroy() :
    在Activity被销毁之前调用。

3、Activity的数据保存

当一个Activity进入到停止状态,是有可能被系统回收的。
如果应用中有一个Activity A,在Activity A的基础上启动了Activity B,此时Activity A就进入停止状态。假设这个时候系统内存不足,Activity A被回收了,那么用户按下Back键返回Activity A,会执行Activity A的onCreate()方法,而不是onResume()方法。
如果Activity A中有一个文本输入框,输入了一段文字后启动Activity B,此时Activity A被系统回收了,按下Back键但会Activity A,会发现输入的文字没了,这个因为Activity A被重新创建。是会影响用户体验的。
Activity中还提供了一个onSaveInstanceState()方法,这个方法在Activity被回收之前一定会被调用,因此我们可以在这个方法中保存一些需要的数据。

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

二、Activity的启动模式

启动模式一共有4种,分别是standard、singleTop、singleTask和singleInstance,可以在AndroidManifest.xml中通过指定android:launchMode=""属性来选择启动模式。
在启动模式之前,我们先来了解任务栈:
Android是使用任务(Task)来管理Activity的,一个任务就是一组存放在栈里的Activity的集合,这个栈也被称作任务栈。
栈是一种后进先出的数据结构,在默认情况下,每启动一个新的Activity,它会在任务栈中入栈,并处于栈顶的位置。当按下Back键或
调用finish()方法去销毁一个Activity时,处于栈顶的Activity会出栈,这时前一个入栈的Activity就会处于栈顶的位置。系统总是会显示处于栈顶的Activity给用户。

1、standard

Activity的默认启动模式。
每当启动一个新的activity,它就会进入任务栈,并处于栈顶的位置。
对于使用standard模式的Activity,系统不会判断该activity在栈中是否存在,每次启动都会创建一个新的实例。
实践:

public class MainActivity extends AppCompatActivity {
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("testStandard", "onCreate: " + this.toString());
        button = findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, MainActivity.class);
                startActivity(intent);
            }
        });
    }
}

在MainActivity中连续按3次Button,可以看到Logcat中打印信息如下

2020-09-29 11:20:19.598 27702-27702/com.android.test D/testStandard: onCreate: com.android.test.MainActivity@21f9bd9
2020-09-29 11:20:21.492 27702-27702/com.android.test D/testStandard: onCreate: com.android.test.MainActivity@4656136
2020-09-29 11:20:21.976 27702-27702/com.android.test D/testStandard: onCreate: com.android.test.MainActivity@a2a137a
2020-09-29 11:20:22.603 27702-27702/com.android.test D/testStandard: onCreate: com.android.test.MainActivity@f705c83

从log中可以看到,每按一次Button,就会创建出一个新的MainActivity实例。此时需要按下4次back键才能退出程序。

2、singleTop

栈顶复用模式
当Activity的启动模式指定为singleTop,在启动Activity时如果发现任务栈的栈顶已经是该Activity,则可以直接使用它,不会再创建新实例。

3、singleTask

栈内复用模式
当Activity的启动模式指定为singleTask,启动该Activity时系统首先会在任务栈中检查是否存在该Activity的实例,如果发现已经存在则直接使用该实例,并把在这个Activity之上的所有Activity统统出栈,如果没有发现就会创建一个新的Activity实例。
实践:
设置MainActivity启动模式为singleTask

        <activity
            android:name=".MainActivity"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

MainActivity跳转到Main2Activity
此时任务栈中包含MainActivity和Main2Activity的实例。位于栈顶的是Main2Activity

public class MainActivity extends AppCompatActivity {
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("testSingleTask", "onCreate: " + this.toString());
        button = findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onRestart() {
        Log.d("testSingleTask", "onRestart: " + this.toString());
        super.onRestart();
    }
}

Main2Activity再跳转到MainActivity
因栈内存在MainActivity,固直接复用。Main2Activity会直接出栈

public class Main2Activity extends AppCompatActivity {
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        Log.d("testSingleTask", "onCreate: " + this.toString());
        button = findViewById(R.id.bt);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Main2Activity.this, MainActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onDestroy() {
        Log.d("testSingleTask", "onDestroy: " + this.toString());
        super.onDestroy();
    }
}

可以看到Logcat中打印信息如下

2020-09-29 13:54:43.576 29601-29601/com.android.test D/testSingleTask: onCreate: com.android.test.MainActivity@21f9bd9
2020-09-29 13:54:45.128 29601-29601/com.android.test D/testSingleTask: onCreate: com.android.test.Main2Activity@88d0837
2020-09-29 13:54:54.997 29601-29601/com.android.test D/testSingleTask: onRestart: com.android.test.MainActivity@21f9bd9
2020-09-29 13:54:55.471 29601-29601/com.android.test D/testSingleTask: onDestroy: com.android.test.Main2Activity@88d0837

4、singleInstance

全局唯一模式
不同于以上3种启动模式,指定为singleInstance模式的Activity会启用一个新的任务栈来管理这个Activity。
实践:
设置Main2Activity启动模式为singleInstance

        <activity
            android:name=".Main2Activity"
            android:launchMode="singleInstance" />

MainActivity跳转到Main2Activity

public class MainActivity extends AppCompatActivity {
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("singleInstance", "MainActivity: " + getTaskId());
        button = findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                startActivity(intent);
            }
        });
    }
}

Main2Activity跳转到Main3Activity

public class Main2Activity extends AppCompatActivity {
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        Log.d("singleInstance", "Main2Activity: " + getTaskId());
        button = findViewById(R.id.bt);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Main2Activity.this, Main3Activity.class);
                startActivity(intent);
            }
        });
    }
}

可以看到Logcat中打印信息如下

2020-09-29 14:09:23.082 29754-29754/com.android.test D/singleInstance: MainActivity: 59
2020-09-29 14:09:25.490 29754-29754/com.android.test D/singleInstance: Main2Activity: 60
2020-09-29 14:09:27.734 29754-29754/com.android.test D/singleInstance: Main3Activity: 59

Main2Activity的Task Id不同于MainActivity和Main3Activity的Task Id,这说明Main2Activity确实是存放在一个单独的任务栈里。
按下Back键进行返回,会发现Main3Activity直接返回到了MainActivity,再按下Back键又会返回到Main2Activity,再按下Back键才会退出程序。
这是由于MainActivity和Main3Activity是存放在同一个任务栈,当在Main3Activity的界面按下Back键,Main3Activity会从任务栈中出栈,那么MainActivity就会在栈顶。因此也就出现了从Main3Activity直接返回到MainActivity的情况。然后在MainActivity界面再次按下Back键,这时当前的任务栈已经空了,于是就显示了另一个任务栈的栈顶Activity,也就是Main2Activity。最后再次按下Back键,这时所有任务栈都已经空了,也就退出了程序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值