Activity的四种启动模式

本文深入解析了Android中Activity的四种启动模式:standard、singleTop、singleTask和singleInstance,阐述了它们在不同场景下的工作原理及如何在AndroidManifest中进行配置。通过具体代码示例,展示了Activity之间的跳转及数据传递过程。

Activity的android:launchMode属性(四种启动模式)(在AndroidManiFest配置)

  1. standard:标准模式,默认
  2. singleTop:Task栈顶复用模式
  3. singleTask:Task栈内复用模式
  4. singleInstance:全局单例模式

Activity是由谁管理的

  • Activity是由任务栈管理的,每启动一个Activity,就会被放入栈中,按返回键,就会从栈顶移除一个Activity
  • standard是默认的启动模式,即标准模式。每启动一个Activity,都会创建一个新的实例

singleTOP模式

  • 当要启动的目标Activity已经位于栈顶的时候,不会创建新的实例,会复用栈顶Activity,并且其onNewIntent()方法会被调用;如果目标Activity不在栈顶,则跟standard一样创建新的实例
  • 在这里插入图片描述

singleTask

  • 在同一个任务栈中,如果要启动的目标Activity已经在栈中,则会复用该Activity,并调用其onNewIntent()方法,并且该Activity上面的Activity会被清除;如果栈没有就会创建新的实例

SingleInstance

  • 全局复用,不管哪个Task栈,只要存在目标Activity,就复用。每个Activity占有一个新的Task栈

package com.example.test0508.jump;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.example.test0508.R;

public class AActivity extends AppCompatActivity {

    private Button mBtnJump1;
    private Button mBtnJump2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_a);
        Log.d("AActivity","--onCreate--");
        Log.d("AActivity","taskId:" + getTaskId()+"  ,hashCode" + hashCode());
        /**
         * 数据传递
         */
        mBtnJump1 = findViewById(R.id.btn_jump1);
        mBtnJump1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(AActivity.this,BActivity.class);//从Activity.this跳到B.class
                //数据传递
                Bundle bundle = new Bundle();
                bundle.putString("name","李");
                bundle.putInt("age",21);
                intent.putExtras(bundle);
                startActivity(intent);
                //这个0是请求码,判断哪一个控件返回
//                startActivityForResult(intent,0);
            }
        });
        mBtnJump2 = findViewById(R.id.btn_jump2);
        mBtnJump2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(AActivity.this,AActivity.class);
                startActivity(intent);
            }
        });
    }


    /**
     * 接受B返回的数据
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Toast.makeText(AActivity.this,"返回的数据"+data.getExtras().getString("title"),Toast.LENGTH_SHORT).show();
    }

    /**
     * 打印任务栈相关信息
     */


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d("AActivity","--onNewIntent--");
        Log.d("AActivity","taskId:" + getTaskId()+"  ,hashCode" + hashCode());
    }
}

package com.example.test0508.jump;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.example.test0508.R;


public class BActivity extends AppCompatActivity {


    private TextView mTvTitle;
    private Button mBtnFinish;
    private Button mBtnBtoA;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);
        mTvTitle = findViewById(R.id.tv_jump_title);


        Log.d("BActivity","--BonCreate--");
        Log.d("BActivity","taskId:" + getTaskId()+"  ,hashCode" + hashCode());

        /**
         * 从A那边获取数据并设置到自己的text里面
         */
        final Bundle bundle = getIntent().getExtras();
        String name = bundle.getString("name");
        int age = bundle.getInt("age");
        mTvTitle.setText("name:" + name + "age" + age);

        /**
         * 结束按钮,并返回数据给A
         */
        mBtnFinish = findViewById(R.id.btn_jump_finish);
        mBtnFinish.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                Bundle bundle1 = new Bundle();
                bundle1.putString("title","我回来了");
                intent.putExtras(bundle1);
                setResult(Activity.RESULT_OK,intent);
                finish();//关闭掉
            }
        });
        mBtnBtoA = findViewById(R.id.btn_jump_btoA);
        mBtnBtoA.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(BActivity.this,AActivity.class);
                startActivity(intent);
            }
        });

    }




    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d("BActivity","--BonNewIntent--");
        Log.d("BActivity","taskId:" + getTaskId()+"  ,hashCode" + hashCode());
    }
}

Android中Activity启动模式(Launch Mode)定义了Activity在任务栈中的行为方式。共有四种启动模式:`standard`、`singleTop`、`singleTask`和`singleInstance`,它们决定了Activity实例的创建方式、任务栈的归属以及如何响应启动请求。 ### `standard` 模式 这是默认的启动模式。每次启动该模式的Activity时,都会创建一个新的实例,并将其压入启动它的Activity所在的任务栈中。即使该Activity已经在栈顶,也不会复用,而是新建一个实例[^4]。 ### `singleTop` 模式 如果目标Activity已经位于任务栈的栈顶,则不会创建新的实例,而是直接使用栈顶的实例,并调用其`onNewIntent()`方法。但如果该Activity不在栈顶,或者任务栈不存在,则仍然会创建新的实例。此模式适用于某些需要避免重复创建栈顶实例的场景,例如通知栏点击跳转。 ### `singleTask` 模式 这种模式的Activity在系统中只会存在一个实例。系统会在启动该Activity时查找是否存在一个任务栈中已经包含该实例。如果存在,则不会创建新实例,而是将该任务栈带到前台,并结束位于该Activity实例之上的所有其他Activity,使其位于栈顶;如果不存在,则会创建一个新的任务栈并放入该实例作为根Activity[^3]。需要注意的是,官方文档虽然指出该模式的Activity通常作为任务的根Activity,但实际行为取决于任务栈的配置和启动上下文。 ### `singleInstance` 模式 该模式的Activity在整个系统中只有一个实例,并且该实例独立存在于一个单独的任务栈中。任何应用启动该Activity时,都会使用这个全局唯一的实例,并将其任务栈置于前台。适用于需要全局共享的界面,例如全局设置或登录界面。由于该模式的Activity独占一个任务栈,后续的Activity启动不会压入该栈中,而是进入其他任务栈。 ## 启动模式的区别总结 - **实例唯一性**:`standard`和`singleTop`允许在多个任务栈中存在多个实例;`singleTask`确保一个系统内仅有一个实例;`singleInstance`确保全局唯一实例并独立任务栈。 - **任务栈行为**:`standard`和`singleTop`的实例压入启动它们的Activity所在任务栈;`singleTask`可能复用已有任务栈或新建任务栈;`singleInstance`始终位于独立任务栈。 - **复用机制**:`standard`始终新建实例;`singleTop`仅在栈顶时复用;`singleTask`在系统中复用;`singleInstance`全局复用。 ### 示例代码:在AndroidManifest.xml中设置启动模式 ```xml <activity android:name=".MainActivity" android:launchMode="singleTask" /> ``` ### 示例代码:通过Intent启动不同模式的Activity ```java Intent intent = new Intent(this, TargetActivity.class); startActivity(intent); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值