2016年11月4日金曜日

[Android] アプリケーションがフォアグラウンドかどうかを判定する

対象

APIレベル24以前の全バージョン

何がしたい?

アプリ内から自分自身がフォアグラウンドかどうかを判定したい。
Activity遷移時に一瞬バックグラウンドになって欲しくない。

結論

Activity#onResumeとActivity#onPauseの回数を数えて、onResumeの方が多いとき、Activityはフォアグラウンド状態である。
Activity遷移時に一時的にフォアグラウンド状態でなくなる。

Activity#onStartとActivity#onStopの回数を数えて、onStartの方が多いとき、Activityはは表示中である。
Activity遷移時に一時的に非表示状態にならない。

用途に応じてどっちかをアプリケーションがフォアグラウンドであると定義して使用すべし。

なんで?

Android DevelopersのActivityのドキュメントを読むとこう書いてある。
The visible lifetime of an activity happens between a call to onStart() until a corresponding call to onStop(). During this time the user can see the activity on-screen, though it may not be in the foreground and interacting with the user. Between these two methods you can maintain resources that are needed to show the activity to the user. For example, you can register a BroadcastReceiver in onStart() to monitor for changes that impact your UI, and unregister it in onStop() when the user no longer sees what you are displaying. The onStart() and onStop() methods can be called multiple times, as the activity becomes visible and hidden to the user.
The foreground lifetime of an activity happens between a call to onResume() until a corresponding call to onPause(). During this time the activity is in front of all other activities and interacting with the user. An activity can frequently go between the resumed and paused states -- for example when the device goes to sleep, when an activity result is delivered, when a new intent is delivered -- so the code in these methods should be fairly lightweight.
onStartからonStopの間はvisible lifetimeで、onResumeからonPauseの間はforeground lifetimeであると。ただこれはActivityの状態のおはなしなので、アプリケーションとは直接関係ない。

Activity遷移時のonResume, onPause, onStart, onStopが呼ばれる順番を見てみと、以下の順番で呼び出されるのでonPauseとonResumeを数える方式では一時的に状態が変化する。
onStopとonStartを数える方式では一時的に状態が変化しない。

A→B遷移時

  1. A#onPause
  2. B#onStart
  3. B#onResume
  4. A#onStop

onPause, onResumeはこの順番で呼ばれるので、Android Developers的には一時的にバックグラウンドになるけど、onStop, onStartは呼ばれる順番が逆なのでAndroid Developers的には一時的に両方表示状態になる。

関連記事

まあこれぐらいのことは前例があるわけで
ただアプリケーションのフォアグラウンドとActivityのフォアグラウンドを分けて考えていない節があるので気をつけよう。

ソースコード

APIレベル14以上ではActivityLifecycleCallbacksなんてのが実装されているのでこちらを使うとActivityの基底クラスを作らなくてよくて楽な模様。
但しバックポートされてない。

以下、例はonStart,onStopを数える方式。
利用は全てのActivityをBaseActivityの派生クラスにして、HogeActivity.getInstance().isForeground()で判定する。


0 件のコメント:

コメントを投稿