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,把自己作为栈顶跟栈底

posted @ 2015-09-25 22:41  小白屋  阅读(1158)  评论(0编辑  收藏  举报