Activity四种启动模式

目录

0、相关文章:

1、standard-默认模式

2、singleTop-栈顶复用模式

2.1、配置形式:

2.2、总结: 

3、singleTask-栈内复用模式

3.1、配置形式:

3.2、总结:

4、singleInstance-全局唯一模式

4.1、配置形式

4.2、案例

5、总结

a.standard:标准模式、默认模式   [ˈstændərd] 

b.singleTop:栈顶复用模式

c.singleTask:栈内复用模式

d.singleInstance:单实例模式


0、相关文章:

彻底弄懂Activity四大启动模式(9w阅读量,46赞,我的正文基本参考此文,只是记录一些不一样的地方,毕竟该文是2016年写的)

细谈Activity四种启动模式(1.4w阅读量,14赞)

Android启动模式之singleinstance的坑(1.4w阅读量,4赞)

Android singleinstance在什么情况下使用(3000阅读量)

android的singleInstance启动模式分解(博客园)

众所周知当我们多次启动同一个Activity时,系统会创建多个实例,并把它们按照先进后出的原则一一放入任务栈中,当我们按back键时,就会有一个activity从任务栈顶移除,重复下去,直到任务栈为空,系统就会回收这个任务栈。但是这样以来,系统多次启动同一个Activity时就会重复创建多个实例,这种做法显然不合理,为了能够优化这个问题,Android提供四种启动模式来修改系统这一默认行为。 
       进入正题,Activity的四种启动模式如下: 
       standard、singleTop、singleTask、singleInstance 
       接下来,我们一边讲理论一边结合案例来全面学习这四种启动模式。 

为了打印方便,定义一个基础Activity,在其onCreate方法和onNewIntent方法中打印出当前Activity的日志信息,主要包括所属的task,当前类的hashcode,以及taskAffinity的值。之后我们进行测试的Activity都直接继承该Activity

public abstract class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LogUtils.e("********************************onCreate()方法**********************************");
        LogUtils.e("onCreate:" + getClass().getSimpleName() + " ,TaskId: " + getTaskId() +
                " ,hasCode:" + this.hashCode());
        dumpTaskAffinity();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        LogUtils.e("********************************onNewIntent()方法**********************************");
        LogUtils.e("onNewIntent:" + getClass().getSimpleName() + " ,TaskId: " + getTaskId() +
                " ,hasCode:" + this.hashCode());
        dumpTaskAffinity();
    }

    protected void dumpTaskAffinity() {
        try {
            ActivityInfo info = this.getPackageManager()
                    .getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
            LogUtils.e("taskAffinity:" + info.taskAffinity);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

}

1、standard-默认模式

这个模式是默认的启动模式,即标准模式,在不指定启动模式的前提下,系统默认使用该模式启动Activity,每次启动一个Activity都会重写创建一个新的实例,不管这个实例存不存在,这种模式下,谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中。这个Activity它的onCreate(),onStart(),onResume()方法都会被调用。 

这个很简单不用多讲,总结:谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中

2、singleTop-栈顶复用模式

这个模式下,如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时它的onNewIntent方法会被调用,通过此方法的参数我们可以去除当前请求的信息。如果栈顶不存在该Activity的实例,则情况与standard模式相同。需要注意的是这个Activity它的onCreate(),onStart()方法不会被调用,因为它并没有发生改变。 

2.1、配置形式:

<activity android:name=".singletop.SingleTopActivity" android:launchMode="singleTop">

2.2、总结: 

standard启动模式是默认的启动模式,每次启动一个Activity都会新建一个实例不管栈中是否已有该Activity的实例。

singleTop模式分3种情况:

  1. 当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法
  2. 当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例
  3. 当前栈中不存在该Activity的实例时,其行为同standard启动模式

standard和singleTop启动模式都是在原任务栈中新建Activity实例,不会启动新的Task,即使你指定了taskAffinity属性。 
那么什么是taskAffinity属性呢,可以简单的理解为任务相关性。

  1. 这个参数标识了一个Activity所需任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名
  2. 我们可以单独指定每一个Activity的taskAffinity属性覆盖默认值
  3. 一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity
  4. 在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务
  5. 为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task

很重要的一点taskAffinity属性不对standard和singleTop模式有任何影响,即时你指定了该属性为其他不同的值,这两种启动模式下不会创建新的task(如果不指定即默认值,即包名) 

3、singleTask-栈内复用模式

  这个模式十分复杂,有各式各样的组合。在这个模式下,如果栈中存在这个Activity的实例就会复用这个Activity,不管它是否位于栈顶,复用时,会将它上面的Activity全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。 

3.1、配置形式:

<activity android:name=".singleTask.SingleTaskActivity" android:launchMode="singleTask" >

3.2、总结:

singleTask启动模式启动Activity时,首先会根据taskAffinity去寻找当前是否存在一个对应名字的任务栈

如果不存在,则会创建一个新的Task,并创建新的Activity实例入栈到新创建的Task中去
如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例 
              如果存在实例,则将它上面的Activity实例都出栈,然后回调启动的Activity实例的onNewIntent方法 
              如果不存在该实例,则新建Activity,并入栈 

此外,我们可以将两个不同App中的Activity设置为相同的taskAffinity,这样虽然在不同的应用中,但是Activity会被分配到同一个Task中去。 

4、singleInstance-全局唯一模式

该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。

4.1、配置形式

<activity android:name=".singleinstance.SingleInstanceActivity" android:launchMode="singleInstance" >

4.2、案例

增加一个Activity如下: 
SingleInstanceActivity.java

import android.os.Bundle;

/**
 * Created by huangshuai on 2016/5/24.
 * Email:huangshuai@wooyun.org
 * SingleInstance模式
 */
public class SingleInstanceActivity extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_singleinstance);
    }
}
配置属性如下:
<activity
    android:name=".ActivitySingleInstance"
    android:launchMode="singleInstance">

    <intent-filter>
        <action android:name="com.castiel.demo.singleinstance" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

使用下面的方式分别在两个应用中启动它

Intent intent = new Intent();
intent.setAction("com.castiel.demo.singleinstance");
startActivity(intent);

做的操作和上一次是一样的,查看日志

我们看到,第一个应用启动SingleInstanceActivity时,由于系统中不存在该实例,所以新建了一个Task,按home键后,使用另一个App进入该Activity,由于系统中已经存在了一个实例,不会再创建新的Task,直接复用该实例,并且回调onNewIntent方法。可以从他们的hashcode中可以看出这是同一个实例。因此我们可以理解为:SingleInstance模式启动的Activity在系统中具有全局唯一性。

注意:自己在实际测试中并没有出现上述情况,而是在进入SingleInstanceActivity时出现如下界面:

每次调用都会出现此界面。也就是说,不可能同时由两个应用同时进入SingleInstanceActivity。

5、总结

a.standard:标准模式、默认模式   [ˈstændərd] 

  • 含义:每次启动一个Activity就会创建一个新的实例。
  •  注意:使用ApplicationContext去启动standard模式Activity就会报错。因为standard模式的Activity会默认进入启动它所属的任务栈,但是由于非Activity的Context没有所谓的任务栈。

b.singleTop:栈顶复用模式

  •  含义:如果新Activity已经位于任务栈的栈顶,就不会重新创建,并回调onNewIntent(intent)方法。

  • 应用场景一:可以解决重复打开activity的问题,例如 点击注册按钮(500毫秒你点击了两次) , 如果你用系统默认的启动模式, 就会打开2个注册页面,singTop启动模式的意思是开启actiivty的时候系统会先判断此activity是否存在栈顶, 如果存在就激活此实例 因此就可以解决上述的问题。

  • 应用场景二:在浏览器的书签 特点:检查栈顶是否存在这个实例 如果存在则不重新创建

c.singleTask:栈内复用模式

  •  含义:只要该Activity在一个任务栈中存在,都不会重新创建,并回调onNewIntent(intent)方法。如果不存在,系统会先寻找是否存在需要的栈,如果不存在该栈,就创建一个任务栈,并把该Activity放进去;如果存在,就会创建到已经存在的栈中。
  • 应用场景:浏览器主页面   特点:该实例在任务栈只能存在一个,如果再启动,则把上面的Activity实例全部清除。A --> B --> C -->D在D点击返回键,就返回到A。

d.singleInstance:单实例模式

  •  含义: 具有此模式的Activity只能单独位于一个任务栈中,且此任务栈中只有唯一一个实例。
  • 应用场景:来电显示界面 特点:该实例Activity会创建一个单独的任务栈,且与用户正在交互的界面的任务栈在    前端,直到全部Activity退出.
     

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值