Android Acitivity启动模式

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启动模式,看看上面的操作会是一个什么效果。这儿我就不再试了!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值