Android中Activity四种加载模式

Activity四种加载模式

        我们知道在配置Activity的时候可以指定android:lauchMode属性,该属性用于配置该Activity的加载模式,概述行支持以下四种:

       1.standard: 标准模式,这是默认的加载模式.

       2.singleTop: Task顶单例模式.
       
       3.singleTask: Task内单例模式.

       4.singleInstance: 全局单例模式.


       那么Activity为什么需要制定加载模式呢?

       由于在Android上启动一个应用后,系统会自动的创建一个属于该应用的Task,也可以理解为Activity栈,先创建的Activity在栈底,后创建的在栈顶部,而Android并没有为我们提供操作Task的相关API,我们无法直接去操作这个Task,只能通过控制Activity的加载模式来控制Activity与Task之间的加载关系了.


       1.standard模式

       以这种模式启动的Activity会创建一个新的Activity实例,并加入到已存在的Task栈中,这种模式不会启动新的.
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        this.setContentView(ll);

        TextView tv = new TextView(this);
        tv.setText("Activity为: " + this.toString()
                + "\n" + ", Task ID 为:" + this.getTaskId());

        Button button = new Button(this);
        button.setText("启动Activity");
        ll.addView(tv);
        ll.addView(button);

        button.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(MainActivity.this, MainActivity.class);
                        startActivity(intent);
                    }
                }
        );
    }

}
技术分享技术分享技术分享
       由于Activity默认的加载模式就是这种,所以不用再AndroidManifest.xml文件中去定义.每次点击按钮之后,都会生成一个新的Activity并加入到栈中,在生成多个之后,不停地按back键,可以看到栈中的Activity一个一个的显示出来.仔细观察每个Activity的HashCode值会有不同,但TaskId都是相同的,说明不会创建新的Task.


2.singleTop模式

       这种模式创建的Activity也是和standard一样直接放栈顶,不同之处在于,singleTop模式在启动Activity之前会检测当前栈顶Activity是否和当前需要启动的Activity是同一类,如果是同一类,系统将直接复用已经拥有的Activity,不是同一类则会和standard模式一样创建一个Activity放到栈顶.


代码和上面的一模一样,需要在AndroidManifest.xml中加入 android:launchMode="singleTop"
技术分享

不管怎么点击按钮,,,,都不会有反应的.


3.singleTask模式

  singleTask模式在加载Activity的时候,只允许同一个Task中存在该Activity的一个实例.创建的时候分三种情况考虑:

        1.如果Task中不存在该Activity的实例,则创建一个加入其中

        2.如果Task中存在并且正好位于栈顶,则与singleTop模式操作方法相同,没有反应.

        3.如果存在Task中,并且不在栈顶,则先将Task中位于该Activity之上的Activity全部弹出,使其置于栈顶.

        注意在AndroidManifest.xml文件中做出相应的更改.
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        this.setContentView(ll);

        TextView tv = new TextView(this);
        tv.setText("Activity为: " + this.toString()
                + "\n" + ", Task ID 为:" + this.getTaskId());

        Button button = new Button(this);
        button.setText("启动Activity");
        ll.addView(tv);
        ll.addView(button);

        button.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                        startActivity(intent);
                    }
                }
        );
    }
}

public class SecondActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        this.setContentView(ll);

        TextView tv = new TextView(this);
        tv.setText("Activity为: " + this.toString()
                + "\n" + ", Task ID 为:" + this.getTaskId());

        Button button = new Button(this);
        button.setText("启动Activity");
        ll.addView(tv);
        ll.addView(button);

        button.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(SecondActivity.this,MainActivity.class);
                        startActivity(intent);
                    }
                }
        );
    }
}

      点击第一个activity中的按钮后,会启动第二个activity,在第二个activity中点击按钮,会将第二个activity中弹出,显示出第一个activity.在第一个activity中按下back按键,会直接退出程序,这就说明第二个activity消失了.如果是在第二个activity中按下back键,则会回退到第一个activity中去.



4.singleInstance模式

    这个加载模式会和前面几个有较大的区别,系统保证无论从哪个Task中启动目标activity,智慧创建一个目标activity实例,并会使用一个全新的Task栈来存放该实例.在创建的时候分如下的两种情况:

            1.目标Activity没有实例存在于Task中,则创建目标Activity实例后,存放在一个单独的Task中.
  
            2.存在实例于Task中,不管是哪个Task(不管是后面创建的Task还是主程序在最初创建的Task),系统都会将那个Task转入前台,使其显示出来.

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        this.setContentView(ll);

        TextView tv = new TextView(this);
        tv.setText("Activity为: " + this.toString()
                + "\n" + ", Task ID 为:" + this.getTaskId());

        Button button = new Button(this);
        button.setText("启动Activity");
        ll.addView(tv);
        ll.addView(button);

        button.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                        startActivity(intent);
                    }
                }
        );
    }
}

public class SecondActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        this.setContentView(ll);

        TextView tv = new TextView(this);
        tv.setText("Activity为: " + this.toString()
                + "\n" + ", Task ID 为:" + this.getTaskId());

        Button button = new Button(this);
        button.setText("启动Activity");
        ll.addView(tv);
        ll.addView(button);

        button.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent();
                        intent.setAction("org.crazyit.intent.action.CRAZYIT_ACTION");
                        startActivity(intent);
                    }
                }
        );
    }
}

 <activity
            android:name="com.example.dada.testapplication.SecondActivity"
            android:launchMode="singleInstance"
            android:exported="true"
            android:label="@string/title_activity_second" >
            <intent-filter>
                <action android:name="org.crazyit.intent.action.CRAZYIT_ACTION" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
技术分享技术分享技术分享

    可以看到在启动了第二个Activity之后,其Task ID变化了,而在第二个Activity正在显示的时候,点击按钮没什么反应.回退到第一个activity再创建第二个Acitivity,Task的ID又出现了不同的数值.

     熟悉了上面的四种加载模式之后,我们就能很方便的管理Activity和Task之间的关系了~~~


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。