Activity的4种加载模式解析:

配置Activity的时候我们可以指定android:launchMode属性,该属性用于配置该Activity的加载模式,支持4个属性值:
1.standard:标准模式,系统默认的加载模式就是这个
2.singleTop:Task顶单例模式
3.singleTask:Task内单例模式
4.singleInstance:全局单例模式
Activity的加载模式的作用:android对Activity的管理是通过Task来管理多个activity的,当我们启动一个应用时,android就会位置创建一个task,我们可以把task理解成activity栈,task以栈的形式来管理activity,先启动的activity被放在task栈底,后面启动的放在上面,这也就是我们所的后进先出,activity的加载模式就负责实例化,加载activity的方式,并可以控制activity与task之间的加载关系。

模式一:standard

特性:这种模式不会启动新的task,新Activity将被添加到远来的task中,也就是说我们通过getTaskId()拿到的id号是同一个,但是activity的对象永远是新的一个,因此我们在task中的效果就是:
这里写图片描述
我们会发现点击三次对象是不断new出来的,因此activity没有复用,而且我们想要返回,是通过点击了4次back才返回的,这是以为启动的时候task中有一个,然后点击了三次,因此必须点击4次task才能清空!并且可以发现taskId是唯一的不变的

**

模式二:singleTop

**
这种模式的启动与standard模式基本相似,
1.只是当将要被启动的目标Activity已经位于Task栈顶时,系统不会重新创建目标Activity的实例
2.当将要被启动的Activity**没有位于Task栈顶时,系统会重新创建新的Activity**并且将它放到task栈顶,此时的特点体现于standard模式完全的相同!
实例演示:
这里写图片描述
点击了3次button,每次的activity都是一样的,说明我们没new新的出来,并且taskId也是同样的一个,测试的时候我们只需要把AndroidManifest.xml中的
lunchMode 由standard 改成 singleTop即可

<activity
    android:name="com.qs.activitylifedemo.StandardTest"
    android:label="@string/app_name" 
    android:launchMode="singleTop"
    >

下面给出上面两个例子的测试code:

public class StandardTest extends Activity {
    private TextView textView;
    private ClickCountUtils utils = ClickCountUtils.getInstance();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout layout = new LinearLayout(this);
        this.setContentView(layout);
        layout.setOrientation(LinearLayout.VERTICAL);
        textView = new TextView(this);
        textView.setText("当前的Activity是"+this.toString()+"\n 当前使用的taskId="+this.getTaskId()+"\n 你点击了"+utils.getClickCount()+"次");
        layout.addView(textView);
        Button button = new Button(this);
        button.setText("点击跳转到taskId为"+getTaskId()+"的界面");
        layout.addView(button);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                utils.addOne();
                textView.setText("当前的Activity是"+StandardTest.this.toString()+"\n 当前使用的taskId="+StandardTest.this.getTaskId()+"\n 你点击了"+utils.getClickCount()+"次");
                Intent intent = new Intent(StandardTest.this,StandardTest.class);
                startActivity(intent);
            }
        });
    }
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        utils.reduceOne();
    }

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

而我们用来统计鼠标点击次数的就是一个简单的单例模式:

public class ClickCountUtils {
    private static ClickCountUtils utils;
    private static int ClickCount=0;
    private ClickCountUtils(){

    }
    public static synchronized ClickCountUtils getInstance(){
        if(utils == null){
            utils = new ClickCountUtils();
        }
        return utils;
    }

    public void addOne(){
        ClickCount++;
        System.out.println(ClickCount);
    }
    public void reduceOne(){
        ClickCount--;
        if(ClickCount<0)ClickCount=0;
    }
    public int getClickCount(){
        System.out.println("getClickCount="+ClickCount);
        return ClickCount;
    }
    public void clearClickCount(){
        ClickCount=0;
    }
}

**

模式三:singleTask

**
采用这种加载模式的Activity 在同一个task内只有一个实例,分为三种情况:
1.如果将要启动的activity不存在,new一个并且添加到task栈顶
2.如果将要启动的activity存在且已经位于栈顶了,此时与singleTop模式行为相同
3.如果将要启动的activity存在但是没有位于栈顶,系统将会把它上面的所有的activity全部移除栈然后让其位于栈顶
这个模式的过程就有点复杂了,我们先通过一个图来了解一下怎么操作的
这里写图片描述
这个上面第一张图片是我们点击了button之后跳到第二个activity之后然后在点击跳回第一个activity的栈的效果,此时和standard模式是一样的因为singleTaskTest模式就是默认模式(standard),我们设置secondActivity模式为singleTask模式,因此点击再次点击singleTaskTest中的button跳到secondActivity的时候我们居然发现了点击事件被重置了,现在显示的是1,因此我们可以大胆的估算是调用了singleTaskTest中的onDestory函数,因为函数的写法是:

@Override
protected void onDestroy() {
    System.out.println("SingleTaskTest call onDestory()");
    super.onDestroy();
    utils.clearClickCount();
}

然后看我们打印的结果:
这里写图片描述
发现函数被调用了,因此得出了当secondActivity想要显示在栈顶的时候,系统强制把位于它上面的所有的activity全部都移除栈顶了,因此我们点击事件才被重置了!
看一下我们的点击效果:
这里写图片描述
动画解析:
当我们进入的时候模式是standard模式的singleTaskTest—(显示点击0次)—>SecondActivity_SingleTask—(显示点击1次)—–>singleTaskTest—–(显示点击两次)—>然后在此点击的时候出发了singleTask的特性,也就是我们上面说的情况3,我们会清除singleTaskTest,因此看到了显示点击了1次(由于ui刷新太快,显示出了第一次的帧界面,暂且这样理解,我也不知道什么问题,知道的朋友还请多多指点一下,多谢!)然后立马显示点击0次,说明我们的singleTaskTest出栈了而且我们发现当显示点击两次的时候和显示0次的时候对象不是同一个对象,一个是2d4 一个是3c8然后点击的时候又出现了52c,这正是我们standard的特性,每次都是new一个新的activity,因此这个又在这里得到证实,最后点击back键的时候我们发现点击了一次,直接退出SecondActivity_SingleTask,然后再点击一次之后从singleTaskTest直接退出了app,因此这里我们可以得出task在SecondActivity_SingleTask在栈顶的时候是两个,你会发现最后一个出栈的永远是我们的第一个进栈的2d4,因此在点击2次的时候退栈需要三次,在点击到SecondActivity_SingleTask界面的时候需要两次,因为清除栈顶,只剩下第一次刚进来时候的栈底和自己本身,所以问题证明完毕!

模式四:singleInstance

在这种加载模式下,系统无论从哪个Task中启动Activity,只会创建一个Activity实例,并且会使用一个全新的栈来装载Activity实例,启动分如下两种情况:
1.如果要启动的Activity实例不存在,那么系统会创建一个全新的Task,再创建目标实例,并将它加入到新栈中
2.如果将要启动的目标Activity已经存在,那么无论位于哪个应用程序中,无论它位于哪个Task中,系统会自动的把该Activity所在的Task转到前台,从而使该Activity显示出来
需要指出的是,采用singleInstance模式加载Activity总是位于Task的顶部,采用这个模式加载的Task只包含这个Activity
下面看一下图片演示:
这里写图片描述
主要观察的是我们的两个taskId,这两个Activity中SecondActivity_SingleInstance 的模式是singleInstance SingleInstanceTest模式是standard,因此我们发现了SecondActivity_SingleInstance 为68 而SingleInstanceTest 为66 这个就是创建一个全新的Task,因此满足了特性1,而特性二我们只需要在创建一个app然后通过intent启动指定action的activity即可做到,这部分将在code中给出,因此不再多说!
效果显示如图:
这里写图片描述
我们可以发现我们从另一个app中直接跳到了我们app的SecondActivity_SingleInstance ,这里显示的就是我们的特性二
后话:貌似图片显示的很快,有点看不清楚,是因为csdn只限制2m,因此只能少帧了,还望谅解!
代码稍后给出,有什么写的不对的地方,还希望各位大神指出来,让我多多长姿势!

Code下载地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值