Android Acitivity启动模式

来源:互联网 发布:css和php哪个好 编辑:程序博客网 时间:2024/05/22 16:49

Activity启动模式对于我们很多应用中会有不同的要求,这儿简单说一下Activity的四种启动模式之间的差别

1.standard默认启动模式,如果不在AndroidMainfest文件中配置,默认为这个模式。

这种模式下,每次启动这个Activity都会调onCreate方法创建新的实例。


示例代码:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Log.i("MainActivity","onCreate  :");    }    public void clickButton(View view) {        startActivity(new Intent(this, MainActivity.class));    }    @Override    protected void onResume() {        super.onResume();        Log.i("MainActivity", " onResume instance :" + this.toString() + "  taskID :" + this.getTaskId());    }}


这儿写一个按钮,点击按钮启动本身,Log可以看出,打印的instance 不相同,taskID 相同,点击返回,不会直接退出应用,而是会闪一下,但是页面显示没变,这就代表是同一个activity的不同实例。

2.singleTop唯一栈顶模式,当启动该activity时,如果该activity有实例在栈顶,就不再重新创建新的实例,而是就用当前栈顶的实例,如果该activity没有实例在栈顶就创建新的实例于栈顶。
    跟第一点中同样的代码,会发现每次点击按钮,不会走onCreate方法去创建新的实例。


3.singleTask当需要启动的activity有实例存在于栈中,就不会再创建新的实例,而是把该实例上面的activity的实例出栈,让该activity位于栈顶,用当前实例。

4.singleInstance该启动模式会单独开辟一个特殊的栈用于存放该activity的实例,当启动别的activity的时候,跳到该进程所处的正常的那个栈,当再次启动该activity的时候,重新跳转到存放该activity的实例的特殊栈。


  好了,上面四种启动方式都已经很详细的说完了,现在我们来一个简单的案例,看看最特殊的一种启动方式singleInstance的特质。为什么说他最特殊呢?因为只有这一种会另外开辟新栈,前面三种虽然有不同,但是因为都是在同一个栈中,所以大同小异!

   现在我们有4个Activity,类名称如下:MainActivity,Main1Activity,Main2Activity,Main3Activity.清单文件中的启动方式,除了Main2Activity之外,其他三个都是默认的启动方式standard启动模式。

清单文件:

<application    android:allowBackup="true"    android:icon="@mipmap/ic_launcher"    android:label="@string/app_name"    android:roundIcon="@mipmap/ic_launcher_round"    android:supportsRtl="true"    android:theme="@style/AppTheme">    <activity android:name=".MainActivity">        <intent-filter>            <action android:name="android.intent.action.MAIN" />            <category android:name="android.intent.category.LAUNCHER" />        </intent-filter>    </activity>    <activity android:name=".Main1Activity" />    <activity        android:name=".Main2Activity"        android:launchMode="singleInstance" />    <activity        android:name=".Main3Activity"/></application>

布局文件都一样,就是有一个按钮,点击启动下一个Activity,button上显示的是当前activity的名字:

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.dragon.upandroiddemos.MainActivity">    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="clickButton"        android:text="MainActivity"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toTopOf="parent" /></android.support.constraint.ConstraintLayout>

Activity中的代码也一样,就是启动下一个activity,并且将当前activity所在栈的ID打印出来:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public void clickButton(View view) {        startActivity(new Intent(this, Main1Activity.class));    }    @Override    protected void onResume() {        super.onResume();        Log.i("MainActivity","onResume taskID :"+getTaskId());    }    @Override    protected void onStart() {        super.onStart();        Log.i("MainActivity","onStart  :");    }}

现在我们做这样的操作,在每一个activity中去启动下一个activity,启动顺序如下:Main----->Main1---->Main2----->Main3----->Main。现在我们来看看log,然后再分析一下。


好了,现在我们再按返回键,观察log结果:

很明显除了Main2在12167栈中,其他三个都在12166栈中。并且按返回键的时候,没有按启动的顺序来返回,现在我们来说说这个过程。

启动过程是调用startActivity方法去创建新的activity并且将当前窗口交给被启动的activity,这个是按前面所说的启动方式正常的启动,没有什么可质疑的。过程如下图:


现在的问题是,现在按返回键的时候,从前面的log很明显的看出,在Main3返回的时候,没有返回到Main2,而是直接回到了Main1。注意这儿就对了。其实系统返回键是将activity栈中的activity出栈的一个过程,也就是说这个过程会连续去操作12166中所存在的activity。当12166栈中的所有activity出栈之后,12167还在当前应用进程中,这时候无法直接退出进程的。需要将12167中的activity也出栈之后将12167栈回收掉。所以才会有上面的这个过程。


好了讲到这儿就差不多完了,网友可以自己试验一下将Main3也该成singleInstance启动模式,看看上面的操作会是一个什么效果。这儿我就不再试了!




1 0
原创粉丝点击