activity启动模式之singleTask

singleTask 的启动模式,网上的资料说的如下

这种方式启动的Activity总是属于一个任务的根Activity,也就是说,如果这个任务不存在,那么会创建一个新的task,然后创建实例,放到这个task最底层

如果这个实例已经存在,那么它会把这个实例上层的所有其他activity实例去掉,使得它成为这个task的顶层实例。但是,我们看下我们的验证

关键代码如下

1.manifest.xml

 <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:logo="@drawable/action_mode_search_normal_white_p"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".HeadSetActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MyActivity1"
            android:label="@string/app_name"
            android:launchMode="singleTask" >
            <intent-filter>
                <action android:name="activity_one" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MyActivity2"
            android:label="@string/app_name"
            android:launchMode="standard" >
            <intent-filter>
                <action android:name="activity_two" />

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

三个activity

HeadSetActivity.java

package com.example.alert;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class HeadSetActivity extends Activity {
    private TextView textView;
    private Button button1;
    private Button button2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tv);
        button1 = (Button) findViewById(R.id.bt1);
        button2 = (Button) findViewById(R.id.bt2);
        button1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                //启动activity1
                Intent intent = new Intent("activity_one");
                startActivity(intent);
            }
        });
        button2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                //启动activity2
                Intent intent = new Intent("activity_two");
                startActivity(intent);

            }
        });

    }

}

MyActivity1.java

package com.example.alert;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MyActivity1 extends Activity {
    private TextView textView;
    private Button button1;
    private Button button2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tv);
        textView.setText("i am activity1");
        button1 = (Button) findViewById(R.id.bt1);
        button1.setText("HeadSetActivity");
        button2 = (Button) findViewById(R.id.bt2);
        button2.setText("Activity2");
        button1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Intent intent = new Intent();
                intent.setClass(MyActivity1.this, HeadSetActivity.class);
                startActivity(intent);

            }
        });
        button2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Intent intent = new Intent("activity_two");
                startActivity(intent);
            }
        });

    }

}

MyActivity2.java

package com.example.alert;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MyActivity2 extends Activity {
    private TextView textView;
    private Button button1;
    private Button button2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tv);
        textView.setText("i am activity2");
        button1 = (Button) findViewById(R.id.bt1);
        button1.setText("HeadSetActivity");
        button2 = (Button) findViewById(R.id.bt2);
        button2.setText("Activity1");
        button1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Intent intent = new Intent();
                intent.setClass(MyActivity2.this, HeadSetActivity.class);
                startActivity(intent);

            }
        });
        button2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Intent intent = new Intent("activity_one");
                startActivity(intent);
            }
        });

    }
}

然后我们进行如下顺序的操作

启动HeadSetActivity->MyActivity1->HeadSetActivity

  Running activities (most recent first):
      TaskRecord{42da7550 #15 A=com.example.alert U=0 sz=3}
        Run #2: ActivityRecord{42f48dc0 u0 com.example.alert/.HeadSetActivity t15}
        Run #1: ActivityRecord{42e99698 u0 com.example.alert/.MyActivity1 t15}
        Run #0: ActivityRecord{42502ae0 u0 com.example.alert/.HeadSetActivity t15}

然后我们在上面操作的基础上,再次跳转到MyActivity1

    Running activities (most recent first):
      TaskRecord{42da7550 #15 A=com.example.alert U=0 sz=2}
        Run #1: ActivityRecord{42e99698 u0 com.example.alert/.MyActivity1 t15}
        Run #0: ActivityRecord{42502ae0 u0 com.example.alert/.HeadSetActivity t15}

从上面我们可以发现两个问题

1.作为singleTask的MyActivity1,确实在实例已经存在的情况下,再次生成会把它前面的activity消除出栈,自己成为栈顶

2.在创建MyActivit1实例的时候,并没有生成新的task。

调查这个问题,我们在网上找到了原因,参考

http://blog.csdn.net/luoshengyang/article/details/6714543

然后我们仅仅验证下

更改manifest.xml如下

 <activity
            android:name=".MyActivity1"
            android:label="@string/app_name"
            android:taskAffinity="com.example.alert.test"
            android:launchMode="singleTask" >
            <intent-filter>
                <action android:name="activity_one" />

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

我们按照如下顺序启动activity

HeadSetActivity->MyActivity1

 Running activities (most recent first):
      TaskRecord{42e54a78 #19 A=com.example.alert.test U=0 sz=1}
        Run #1: ActivityRecord{4342b528 u0 com.example.alert/.MyActivity1 t19}
      TaskRecord{42ccd960 #18 A=com.example.alert U=0 sz=1}
        Run #0: ActivityRecord{43427768 u0 com.example.alert/.HeadSetActivity t18}

我们发现确实生成了一个新的task

如果我们在上面的基础上,再次跳转到HeadSetActivity 如下

 Running activities (most recent first):
      TaskRecord{42e54a78 #19 A=com.example.alert.test U=0 sz=2}
        Run #2: ActivityRecord{42502ae0 u0 com.example.alert/.HeadSetActivity t19}
        Run #1: ActivityRecord{4342b528 u0 com.example.alert/.MyActivity1 t19}
      TaskRecord{42ccd960 #18 A=com.example.alert U=0 sz=1}
        Run #0: ActivityRecord{43427768 u0 com.example.alert/.HeadSetActivity t18}

我们会发现,新的实例HeadSetActivity是跟MyActivity1在同一个栈里面的。当我们再次计划MyActivity1的时候,它会移除它上面的activity,自己成为栈顶。这其实就验证了那句话,

拥有singleTask的activity,永远都会作为一个栈的栈底,哪怕他也可作为栈顶,只不过这时候整个栈就它自己而已

如果这个activity销毁了,那么它所在的栈也就被销毁了。

现在总结如下

1.如果一个activity的launchmode被设置为singleTask,这时候创建它的时候,并不会创建新的task,而是把自己放到父activity同一个栈中,而且,当再次启动它的时候,这个栈里面,在它上面的activity就会被移除出栈,它成为栈顶

2.如果你同时设定了launchmode被设置为singleTask跟android:taskAffinity,那么创建它的activity的时候,同时会创建一个新的task,并把它作为栈底,之后它启动的activity,也会放到这个栈中。当再次启动它的时候,它同样会清除栈内其他的activity,把自己作为栈顶跟栈底

时间: 2024-12-22 14:24:18

activity启动模式之singleTask的相关文章

(原创)Activity启动模式之singleTask

android中activity有四种启动模式 standard(默认):在同一个任务栈中可以有重复的activity,基本没什么限制 singleTop:只有当此activity在栈顶时,去创建它,不会有新的activity生成,而是调用onNewInstance()方法 singleTask:在栈中只有一个activity实例,回调onNewInstance(),会把它之上的activity都finish()掉 singleInstance:会在新的任务栈中创建 设置启动模式在Android

android:Activity启动模式之singleTask(一)

先看一下standard启动模式的说明: 仅仅有一个实例.在同一个应用程序中启动他的时候.若不存在此Activity实例.则会在当前栈顶创建一个新的实例.若存在,则会把栈中在其上的其他Activity实例销毁掉,并调用此实例的OnNewIntent方法,假设实在别的应用实例中启动它.则会新建一个栈,并在该栈中启动这个Activity,然后我在这个Activity实例中再打开新的Activity这个新的实例会在一个栈中 我们首先通过一个实例理解这句:仅仅有一个实例.在同一个应用程序中启动他的时候,

activity启动模式笔记

activity启动模式的逻辑主要在startActivityUncheckedLocked()函数中,现在来看下这个函数. final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doRe

我对standard、singleTop、singleTask和singleInstance四种Activity启动模式的理解

之前自学android的时候,单从视频和书本上对这四种启动模式仅仅有了初步的字面上的理解.最近实战了下,也对这四种启动模式有了比较清晰的概念. 首先说下什么是Activity,按照我的理解,我们在手机上看到的每一个页面都是一个Activity,包括系统的桌面,也是一个Activity. 要启动一个Activity有四种模式:standard(标准启动模式).singleTop.singleTask.singleInstance. 注: Aty1_1和Aty2_1为两个不同的Activity,At

Android多任务切换与Activity启动模式SingleTask之间关系的分析

这里会以多个场景列子进行分析,在分析之前先了解一下基本的概念. Task任务:一系列Activity的集合,这些Activity以栈的形式进行排列(后进先出). 那在什么时候系统会新建一个Task任务呢? 这个要以app来区分(注意,这里看Activity是否属于同一报名),当一个app以singleTask启动方式启动另外一个app的activity时,会新建一个Task任务,而第二个app的Activity会成为这个栈中的根. 反之,在什么时候不会创建新任务呢?当一个app以非SingleT

深入Activity,Activity启动模式LaunchMode完全解析

转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53221384 本文出自[DylanAndroid的博客] 深入Activity,Activity启动模式LaunchMode完全解析 在平时的开发中,我们可能会了解到Activity的任务栈还有Activity的启动模式.那么Activity的启动模式都分别是怎么样的呢?如果设置了这些启动模式对任务栈有事么影响 ,还有就是这么启动模式在实际的开发中有什么应用呢?这里用图例和d

Android中Activity启动模式详解,可以控制程序按home键后进来还会调用一个自己不喜欢的界面

其实这是很简单的一个问题.但是这还是要对android中activity的启动模式有相当的理解才行,当点击home键的时候,懂Android的人都知道,他会把当前activity放到后退栈中, 栈(Stack)又称堆栈,它是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算.人们把此端称为栈顶,栈顶的第一个元素被称为栈顶元素,相对地,把另一端称为栈底.向一个栈插入新元素又称为进栈或入栈,它是把该元素放到栈顶元素的上面,使之成为新的栈顶元素:从一个栈删除元素又称为出栈或退栈,它是把栈

Activity启动模式

在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. Android总Activity的启动模式分为四种: Activity启动模式设置: <activity android:name=".MainActivity" android:launchMode="standard" /> Activity的四种启动模式:

Activity启动模式(launchMode)详解

Activity 的启动模式有四种,standard.singleTop.singleTask.singleInstance. image.png 1.standard standard是Activity默认的启动模式,在不进行显示指定的情况下,所有活动都会自动使用这种启动模式. 每次启动都一个新的Activity位于栈顶. android:launchMode="standard",此时每次点击按钮都会创建新的Activity 现在,我们写一个简单的按钮 ,实现跳转Activity