Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Activity启动模式详解

$
0
0

众所周知,android给我们提供了standardsingleTopsingleTasksingleInstance 4种Activity的启动模式,其中:

standard:标准模式,即默认启动模式;

singleTop:顶单例模式,即要求实例处于栈顶;

singleTask:内单例模式,即要求栈中只有一个实例;

singleInstance:全局单例模式;

接下来将会对以上4种加载模式进行讲解。

1standard模式

每次通过这种模式启动目标Activity时,android总会为目标Activity创建一个新的实例,并将该实例添加到当前的任务栈中,这种模式不会启动新的任务栈,新创建的Activity实例将被添加到原有的任务栈中。如:

public class StandardActivity extends AppCompatActivity {

    private TextView tv_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_standard);
        tv_content = (TextView) findViewById(R.id.tv_content);
        tv_content.setText("当前Activity为:"+"\n"
                +this.toString()
                +"\n"+" TaskId为:"+this.getTaskId());
    }

    public void skip2StandardActivity(View view){
        Intent intent = new Intent(StandardActivity.this,StandardActivity.class);
        startActivity(intent);
    }
}
运行程序,可以发现每次点击StandardActivity都会创建一个新的StandardActivity实例,在控制台中输入:adb shell dumpsys activity然后回车可以看到Activity的栈情况

需要注意的是,Standard加载模式无须配置目标ActivitylaunchMode属性,目标Activity会默认采用standard加载模式。


2singleTop模式

singleTop模式与standard模式基本相似,唯一不同的是,当将要被启动的目标Activity已经处于任务栈栈顶时,系统不会重新创建目标Activity的实例,而是直接复用已有的Activity,当然,如果将要被启动的目标Activity没有位于任务栈栈顶的话,此时系统会重新目标Activity,并将创建的新的Activity实例添加到任务栈中(此时与standard加载模式相同)。如:

public class StandardActivity extends AppCompatActivity {

    private TextView tv_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_standard);
        tv_content = (TextView) findViewById(R.id.tv_content);
        tv_content.setText("当前Activity为:"+"\n"
                +this.toString()
                +"\n"+" TaskId为:"+this.getTaskId());
    }

    public void skip2StandardActivity(View view){
        Intent intent = new Intent(StandardActivity.this,StandardActivity.class);
        startActivity(intent);
    }

    public void skip2SingleTopActivity(View view){
        Intent intent = new Intent(StandardActivity.this,SingleTopActivity.class);
        startActivity(intent);
    }
}

目标SingleTopActivity 的主要代码如下所示:

public class SingleTopActivity extends AppCompatActivity {

    private TextView tv_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_standard);
        tv_content = (TextView) findViewById(R.id.tv_content);
        tv_content.setText("当前Activity为:"+"\n"
                +this.toString()
                +"\n"+" TaskId为:"+this.getTaskId());
    }
    public void skip2StandardActivity(View view){
        Intent intent = new Intent(SingleTopActivity.this,StandardActivity.class);
        startActivity(intent);
    }

    public void skip2SingleTopActivity(View view){
        Intent intent = new Intent(SingleTopActivity.this,SingleTopActivity.class);
        startActivity(intent);
    }
}
另外,需要在AndroidManifest清单文件中为目标SingleTopActivity配置launchMode属性,并将其指定为singleTop,如下所示:

<activity android:name=".SingleTopActivity"
    android:launchMode="singleTop"/>
此时,运行程序可以发现,当在StandardActivity中点击SingleTopActivity按钮时会创建一个SingleTopActivity的实例,当在SingleTopActivity中点击SingleTopActivity按钮时,由于SingleTopActivity已经在任务栈的栈顶,因此不会再创建新的实例,当然,如果在SingleTopActivity中点击StandardActivity按钮回到StandardActivity界面时,此时再点击SingleTopActivity按钮,会发现,又创建了一个新的SingleTopActivity的实例。同样的,在控制台输入:adb shell dumpsys activity命令可以查看Activity的任务栈情况如下所示:


3singleTask模式

采用singleTask加载模式的Activity在同一个任务栈内只有一个实例,当系统采用singleTask模式启动目标Activity时,可分为如下几种情况:

1)如果将要启动的目标Activity不存在,系统将会创建目标Activity的实例,并将它添加到任务栈的栈顶中;

2)如果将要启动的目标Activity已经位于任务栈的栈顶,此时与singleTop模式相同,系统不会重新创建新的目标Activity的实例,而是直接复用已有的Activity实例;

3)如果将要启动的目标Activity已经存在,但没有位于任务栈的栈顶,那么此时系统将会把位于该Activity上面的所有Activity移出任务栈,从而使得目标Activity处于任务栈的栈顶。如

public class StandardActivity extends AppCompatActivity {

    private TextView tv_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_standard);
        tv_content = (TextView) findViewById(R.id.tv_content);
        tv_content.setText("当前Activity为:"+"\n"
                +this.toString()
                +"\n"+" TaskId为:"+this.getTaskId());
    }

    public void skip2StandardActivity(View view){
        Intent intent = new Intent(StandardActivity.this,StandardActivity.class);
        startActivity(intent);
    }
    public void skip2SingleTaskActivity(View view){
        Intent intent = new Intent(StandardActivity.this,SingleTaskActivity.class);
        startActivity(intent);
    }
}
SingleTaskActivity的代码如下所示:

public class SingleTaskActivity extends AppCompatActivity {

    private TextView tv_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_standard);
        tv_content = (TextView) findViewById(R.id.tv_content);
        tv_content.setText("当前Activity为:"+"\n"
                +this.toString()
                +"\n"+" TaskId为:"+this.getTaskId());
    }
    public void skip2StandardActivity(View view){
        Intent intent = new Intent(SingleTaskActivity.this,StandardActivity.class);
        startActivity(intent);
    }

    public void skip2SingleTaskActivity(View view){
        Intent intent = new Intent(SingleTaskActivity.this,SingleTaskActivity.class);
        startActivity(intent);
    }
}
当然,跟singleTop模式一相,同样需要在AndroidManifest清单文件中跟SingleTaskActivity添加launchMode属性并将其指定为singleTask,如下所示:

<activity android:name=".SingleTaskActivity"
    android:launchMode="singleTask"/>
程序运行后,在StandardActivSity中点击SingleTaskActivity按钮跳转到SingleTaskActivity时会创建一个SingleTaskActivity的实例,此时点击StandardActivity按钮跳转到StandardActivity中,在多次点击StandardActivity后,再点击SingleTaskActivity按钮会发现,此时并没有创建新的SingleTaskActivity的实例,并且原先位于SingleTaskActivity实例上面的所有StandardActivity的实例都消失了。



4singleInstance模式

singleInstance这种加载模式可以保证系统无论从哪个任务栈中启动目标Activity,都只会创建一个目标Activity的实例,并会使用一个全新的任务栈来装载该Activity的实例。

当以singleInstance模式启动目标Activity时,可分为如下两种情况:

1)如果将要启动的目标Activity不存在,系统会先创建一个全新的任务栈,再创建目标Activity的实例,并将它加入到新的任务栈的栈顶;

2)如果将要启动的目标Activity已经存在,无论它位于哪个任务栈中,系统都将会把该Activity所在的任务栈转到最前面,从而使该Activity显示出来。

需要注意的是采用singleInstance模式加载的Activity总是位于任务栈的栈顶,并且加载的Activity所在的任务栈中只包含该Activity。代码如下所示:

public class StandardActivity extends AppCompatActivity {

    private TextView tv_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_standard);
        tv_content = (TextView) findViewById(R.id.tv_content);
        tv_content.setText("当前Activity为:"+"\n"
                +this.toString()
                +"\n"+" TaskId为:"+this.getTaskId());
    }

    public void skip2StandardActivity(View view){
        Intent intent = new Intent(StandardActivity.this,StandardActivity.class);
        startActivity(intent);
    }
    public void skip2SingleInstanceActivity(View view){
        Intent intent = new Intent(StandardActivity.this,SingleInstanceActivity.class);
        startActivity(intent);
    }
}
SingleInstanceActivity的代码如下所示:

<span style="font-size:12px;">public class SingleInstanceActivity extends AppCompatActivity {

    private TextView tv_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_standard);
        tv_content = (TextView) findViewById(R.id.tv_content);
        tv_content.setText("当前Activity为:"+"\n"
                +this.toString()
                +"\n"+" TaskId为:"+this.getTaskId());
    }
    public void skip2StandardActivity(View view){
        Intent intent = new Intent(SingleInstanceActivity.this,StandardActivity.class);
        startActivity(intent);
    }
    public void skip2SingleInstanceActivity(View view){
        Intent intent = new Intent(SingleInstanceActivity.this,SingleInstanceActivity.class);
        startActivity(intent);
    }
}</span><span style="font-size:14px;">
</span>
AndroidManifest清单文件中给SingleInstanceActivity添加launchMode属性并将其指定为singleInstance,代码如下所示:

<activity android:name=".SingleInstanceActivity"
    android:launchMode="singleInstance"/>
运行程序可以看出,当在StandardActivity中点击SingleInstanceActivity按钮时,如果SingleInstanceActivity实例不存在,则会先创建一个SingleInstaceActivity的实例,在SingleInstaceActivity中点击StandardActivity按钮回到StandardActivity后,连续点击几次StandardActivity按钮进行跳转后再点击SingleInstanceActivity按钮会发现SingleInstanceActivity并没有再次创建新的实例。同样的,在控制台通过:adb shell dumpsys activity命令可以查看Task栈的情况,从结果中可以发现点击SingleInstanceActivity按钮时新创建了一个任务栈并将新创建的SingleInstanceActivity的实例添加到了该任务栈中。



此时,关于Activity的启动模式就算是已经讲解完了。

 源码

作者:u010933680 发表于2016/8/21 18:10:54 原文链接
阅读:38 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>