woshidan's blog

あいとゆうきとITと、とっておきの話。

launchModeをsingleTopにしておくと何が起こるか

二重Activity起動、嫌、絶対。

というとき、自分の場合は以下の二つのような場合があります。

  • フォームを連打したところ、その結果のActivityが何個も起動される
  • 2つ行き来したいActivityがあって、Intentを送り合ったりしているうちに両方がずんずんどこどこスタックされる

前者の場合の、Activityの二重起動には連打自体の対策と、launchModeを云云かんぬんと聞いたことあって、launchModeがよく分からなかったため、 Android開発でよく利用されるデフォルトのlaunchModeとsingleTopの場合を比較しました。

コード

android-activity-launchmode · GitHub

// Homeボタンを押せばintentでstartActivityでMainActivityを起動する

        drawer = new DrawerBuilder()
                .withActivity(this)
                .withToolbar(toolbar)
                .withActionBarDrawerToggle(true)
                .addDrawerItems(
                        item1
                )
                .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
                    @Override
                    public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
                        // do something with the clicked item :D
                        Log.d("Drawer", "position: " + position);
                        MainActivity.this.closeDrawer();
                        Intent intent = new Intent(MainActivity.this, MainActivity.class);
                        startActivity(intent);
                        return false;
                    }
                })
                .build();

デフォルト

startActivityの度に新しいActivityのインスタンスを生成してスタック。

f:id:woshidan:20160117220030g:plain

singleTop

同じクラスのインスタンスがタスク*1のトップにある時は、新しいインスタンスを生成せず、いまのインスタンスを利用します。

f:id:woshidan:20160117220544g:plain

なので、今回のMainActivityからMainActivityを呼び出すということをした場合はバックスタックに新しくつまれるMainActivityは無いし、他のActiivtyから二重にMainActivityを呼び出してしまったという場合は、バックスタックに新しくつまれるMainActivityは1つです。

まあ、singleTopってそういうものだろー!って言われたら、はいっ、そうですーって感じですが。

また、この場合、onStart()の前にonNewIntent()とonRestart()というライフサイクルメソッドが呼び出されるので、必要あれば、オーバーライドしましょう。

参考: Android - Activity のライフサイクル再確認 - Qiita

Activityの行き来の中で複数起動を防止したい

同じTaskの中に1つしかActivityを持ちたくない場合は、名前的にsingleTaskなどが該当しそうですが、公式から利用が推奨されてはいないらしいので、どちらが先に表示されているActivityかを確認し、後から呼び出す方から先に表示されている方へ戻る時はfinish()などで後から表示されている方を閉じておけばいいのかな、と現状考えています。

*1:これは別のアプリとの連携なども含めたユーザーから見たアプリ単位のActivityのスタックで、おおむねの場合、自分のアプリのスタックと理解してます