zoukankan      html  css  js  c++  java
  • Android活动的启动模式

    在实际的项目中,我们应该根据特定的需求为每个活动指定恰当的启动模式。活动的启动模式一共有四种,可以在AndroidManifest.xml中通过给<activity>标签指定android:launchMode属性来选择启动模式。下面我们来逐一介绍:
    (1)standard:活动的默认启动模式,在standard模式下,每当启动一个新的活动,它就会在返回栈中入栈,并置于栈顶的位置。对于使用standard模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。
    代码实例:

     1 @Override
     2 protected void onCreate(Bundle savedInstanceState) {
     3     super.onCreate(savedInstanceState);
     4     setContentView(R.layout.activity_main);
     5 
     6     Log.d(TAG, this.toString());
     7     btn_jump = findViewById(R.id.btn_jump);
     8     btn_jump.setOnClickListener(new View.OnClickListener() {
     9     @Override
    10     public void onClick(View v) {
    11         Intent intent = new Intent(MainActivity.this,MainActivity.class);
    12         startActivity(intent);
    13         }
    14     });
    15 }

    运行程序,然后在连续点击两次跳转按钮,可以看到logcat中打印的信息如下:

    从打印的信息我们可以看出,每点击一次按钮就会创建一个新的MainActivity实例。此时返回栈中也会存在三个MainActivity的实例,因此你需要连按3次Back键才能退出程序。

    (2)singleTop:在启动活动的时候如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。
    修改AndroidManifest.xml中MainActivity的启动模式,如下所示:

    1 <activity 
    2 android:name=".MainActivity"
    3 android:launchMode="singleTop">
    4 <intent-filter>
    5 <action android:name="android.intent.action.MAIN" />
    6 
    7 <category android:name="android.intent.category.LAUNCHER" />
    8 </intent-filter>
    9 </activity>

    运行程序,查看logcat会看到已经创建了一个MainActivity的实例,如图所示:

    但是之后不管你点击多少次按钮都不会再有新的打印信息出现,因为目前MainActivity已经处于返回栈的栈顶,每当你想再启动一个MainActivity时都会直接使用栈顶的活动,所以MainActivity也只会有一个实例,仅按一次Back键就可以退出程序。

    不过当MainActivity并未处于栈顶位置时,这时再启动MainActivity,还是会创建新的实例的。

    (3)singleTask:当活动的启动模式指定为singleTask,每次启动该活动时,系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
    修改AndroidManifest.xml中MainActivity的启动模式,如下所示:

    1 <activity
    2 android:name=".MainActivity"
    3 android:launchMode="singleTask">
    4 <intent-filter>
    5 <action android:name="android.intent.action.MAIN" />
    6 
    7 <category android:name="android.intent.category.LAUNCHER" />
    8 </intent-filter>
    9 </activity>

    然后在MainActivity中添加onRestart()方法,并打印日志:

    1 @Override
    2 protected void onRestart() {
    3     super.onRestart();
    4     Log.d("MainActivity","onRestart");
    5 }

    新建一个activity:JumpActivity,并添加onDestroy()方法,并打印日志:

    1 @Override
    2 protected void onDestroy() {
    3     super.onDestroy();
    4     Log.d("JumpActivity","onDestroy");
    5 }

    在JumpActivity界面布局中添加一个Button控件,添加点击事件使其跳回MainActivity:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3 xmlns:app="http://schemas.android.com/apk/res-auto"
     4 xmlns:tools="http://schemas.android.com/tools"
     5 android:layout_width="match_parent"
     6 android:layout_height="match_parent"
     7 tools:context=".JumpActivity">
     8 
     9     <Button
    10     android:text="跳回去玩一下"
    11     android:id="@+id/btn_jump_back"
    12     android:layout_width="wrap_content"
    13     android:layout_height="wrap_content" />
    14 
    15 </android.support.constraint.ConstraintLayout>
    1 Button btn_jump_back = findViewById(R.id.btn_jump_back);
    2 btn_jump_back.setOnClickListener(new View.OnClickListener() {
    3     @Override
    4     public void onClick(View v) {
    5     Intent intent = new Intent(JumpActivity.this,MainActivity.class);
    6     startActivity(intent);
    7     }
    8 });

    最后修改Button的点击事件,使其跳转到JumpActivity界面:

    1 btn_jump.setOnClickListener(new View.OnClickListener() {
    2     @Override
    3     public void onClick(View v) {
    4     Intent intent = new Intent(MainActivity.this,JumpActivity.class);
    5     startActivity(intent);
    6     }
    7 });

    运行程序,在MainActivity界面点击按钮进入到JumpActivity,然后在按JumpActivity中的返回按钮,又会进入到MainActivity,查看logcat中的打印信息:

    其实从打印信息中就可以看出了,在JumpActivity中启动MainActivity时,会发现返回栈中已经存在了一个MainActivity实例,并且在JumpActivity的下面,于是JumpActivity会从返回栈中出栈,而MainActivity重新成为了栈顶活动,因此MainActivity中的onRestart()方法和JumpActivity的onDestroy()方法会执行。现在返回栈中只剩下一个MainActivity的实例了,按一下Back键就可以退出程序。

    (4)singleInstance:指定为singleInstance模式的活动会启动一个新的返回栈来管理这个活动。
    适用场景:共享活动实例的问题
    代码测试:
    修改AndroidManifest.xml中JumpActivity的启动模式:

    1 <activity
    2 android:name=".JumpActivity"
    3 android:launchMode="singleInstance">
    4 
    5 </activity>

    然后修改MainActivity中onCreate()方法的代码:

    1 Log.d("MainActivity", "Task id is "+getTaskId());
    2 btn_jump = findViewById(R.id.btn_jump);
    3 btn_jump.setOnClickListener(new View.OnClickListener() {
    4 @Override
    5 public void onClick(View v) {
    6     Intent intent = new Intent(MainActivity.this,JumpActivity.class);
    7     startActivity(intent);
    8     }
    9 });

    在JumpActivity的onCreate()方法中打印当前返回栈的ID:

    1 Log.d("JumpActivity", "Task id is "+getTaskId());

    并修改它的点击事件:

    1 btn_jump_back.setOnClickListener(new View.OnClickListener() {
    2     @Override
    3     public void onClick(View v) {
    4         Intent intent = new Intent(JumpActivity.this,ThirdActivity.class);
    5         startActivity(intent);
    6     }
    7 });        

    创建一个TiridActivity,同上修改onCreate()方法:

    1 Log.d("ThirdActivity","Task id is "+getTaskId());

    运行程序:在MainActivity界面点击按钮进入JumpActivity,然后再点击按钮进入TiridActivity。

    查看logcat中的打印信息,如图所示:

    可以看到,JumpActivity的Task id不同于MainActivity和TiridActivity,这说明JumpActivity确实存放在一个单独的返回栈中,而且这个栈中只有JumpActivity这一个活动。然后我们按下Back键进行返回,你会发现TiridActivity直接返回到了MainActivity,再按下Back键又会返回到JumpActivity,再按下Back键才会退出程序。原因:由于MainActivity和TiridActivity是存放在同一个栈里面的,当在TiridActivity界面按下Back键,TiridActivity会从返回栈中出栈,那么MainActivity就会成为栈顶活动显示在界面上,因此也就出现了从TiridActivity直接返回到了MainActivity的情况。然后在MainActivity界面再次按Back键,这时当前的返回栈已经空了,于是显示了另一个返回栈的栈顶活动,即JumpActivity。最后再按Back键,这时所有返回栈都已经空了,也就自然退出了程序。

  • 相关阅读:
    数据结构—链表
    python字母串查找基本操作
    python九九乘法表程序代码
    SpringMVC跨域问题排查以及源码实现
    深入理解MySql子查询IN的执行和优化
    Dubbo源码阅读-服务导出
    Disconf源码分析之启动过程分析下(2)
    Disconf源码分析之启动过程分析上(1)
    Java多线程volatile和synchronized总结
    Java多线程基础总结
  • 原文地址:https://www.cnblogs.com/remote/p/10136955.html
Copyright © 2011-2022 走看看