Activity启动模式(一)之singleTask+finish()退出应用程序

开个头

在一篇公众号中看到了,优雅退出anroid应用程序的方法,优雅地退出应用。
其中提到了一种用SingleTask+finish()的方法退出android应用。我们来简单的看一下。

简单分析四种启动模式

standard

标准模式:也是默认的启动模式,就是每次启动该Activity的时候,都会重新创建该Activity的实例,并不会考虑当前activity栈里面是否有该Activity的实例,而是直接压栈。

singleTop

栈顶复用模式:就是启动一个Activity的时候,如果栈顶有该Activity的实例,就不会新创建实例,而是复用这个已经存在的实例。如果栈里没有Activity的实例,或者有实例但是不在栈顶,都会重新创建该Activity的实例并且压栈。

需要注意的是如果复用了实例,会回调一个onNewIntent()的方法。

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        mFragments.noteStateNotSaved();
    }

singleTask

栈内复用模式:和singleTop类似,不同的地方是,他是判断栈内是否存在该Activity的实例,而且,一旦栈内存在实例,他会直接将该实例之上所有的activity出栈,也就是都finish()掉,把该实例置于栈顶。如果不存在实例,那么才会重新创建该Activity的新实例,并且压栈。
和singleTop一样,如果复用了实例,会调用onNewIntent()方法

singleInstance

单一实例模式:整个手机系统中只有该Activity的一个实例。并且该实例单独存在一个activity栈中。

优雅退出应用

我们先假定一种需求,就是打开应用后,点击进入一个设置界面,在设置界面点击一个退出按钮,整个应用退出。
Activity启动模式(一)之singleTask+finish()退出应用程序_第1张图片

步骤分析:
启动程序,启动MainActivity界面,MainActivity实例被压栈。

点击跳转按钮,跳转到SettingActivity界面,并且通过Intent传递了一个boolean类型的参数”isExit”,SettingActivity实例被压栈。注意,跳转的时候没有调用MainActivity的finish()方法,所以,此时栈底到栈顶的顺序为MainActivity –>SettingActivity

点击退出按钮,跳转到MainActivity界面,由于MainActivity的launcher为singleTask,所以会回调onNewIntent方法,接收intent值,收到SettingActivity传来的boolean值”isExit”为true,调用MainActivity的finish()方法,并且会把activity栈里的MainActivity实例之上的所有Activity弹出栈,也就是SettingActivity被finish()掉。最后整个应用退出。
log分析:
Activity启动模式(一)之singleTask+finish()退出应用程序_第2张图片
intent分析
这里有个要注意的地方就是intent这个东西。在onNewIntent(intent)这个方法里收到的intent是最新的intent,而直接通过getIntent()方法获取的intent是启动应用时 启动MainActivity的intent。必须通过setIntent(intent)方法之后,才可以通过getIntent()方法获取最新的intent值。
Activity启动模式(一)之singleTask+finish()退出应用程序_第3张图片

以上只是对singleTask这种模式做了简单的分析,要注意的点就是。
如果栈里有该Activity的实例,那么跳转的时候:
1、会复用栈里的activity的实例,会调用onNewIntent方法,接收intent值
2、先调用onNewIntent(),然后才会调用onResume()。上面的例子,没有调用onResume是因为直接在onNewIntent()里面调用了finish(),所以还没来得onResume()界面就没了。也正因为这个原因,所以才并没有出现界面先跳到MainActivity然后再退出,而造成的视觉闪退的情况。
3、把栈内该activity实例之上的所有实例 都弹出栈也就是finish()掉。
4、singleTask启动模式,并没有对应的ACTION_FLAG与之对应,所以不能通过Intnent.setFlag
的方法设置,只能通过在清单文件设置android:launchMode的方法设置。
5、必须先setIntent(intent)之后,才能用getIntent()方法获取最新的intent值。

其实singleTask还有其他的用法,之后再分析。
manifest文件

<activity
    android:name=".MainActivity"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    intent-filter>
activity>
<activity android:name=".SettingActivity" />

MainActivity:

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    //跳转到SettingActivity界面
    public void jumpToSetting(View view) {
        Intent intent = new Intent(this, SettingActivity.class);
        startActivity(intent);
    }


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e(this.toString(), "----------------------------------onNewIntent---------------------------------");

        Intent intentBefore = getIntent();
        boolean isExitBefore = intentBefore.getBooleanExtra("isExit", false);

        setIntent(intent);

        Intent intentAfter = getIntent();
        boolean isExiAfter = intentAfter.getBooleanExtra("isExit", false);

        detailIntent(intent);
    }

    private void detailIntent(Intent intent) {
        if (intent != null) {
            boolean isExit = intent.getBooleanExtra("isExit", false);
            Log.e("dealIntent", "isExit = " + isExit);
            if (isExit) {
                finish();
            }
        }
    }
}

SettingActivity:

public class SettingActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_setting);
    }

    //跳转到MainActivity
    public void exit(View view) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra("isExit", true);
        startActivity(intent);
    }
}

你可能感兴趣的:(Android开发碎片)