はじめに
アプリ復帰時の処理をonResumeで行うと通常のActivity遷移でも反応してしまうので困っていました。
(諸般の事情でAcitivityを多用するアプリだったので)
isOnCreate のようなフラグ管理やIntent呼び出し時にフラグをつけるなど考えましたが、
いまいちスマートではなく...
そんな時、この記事を発見して、参考に取り組みました。
アプリのバックグラウンド⇆フォアグラウンドを検知する。ProcessLifecycleOwnerの導入
ProcessLifecycleOwnerでアプリのバックグラウンド移行とフォアグラウンド復帰を検知する
正直、前出の記事の焼き増しか劣化版になりますが、自分用の備忘録に残します。
ケーススタディ
ソースは こちら です
今回は、ProcessLifeCycleOwner + Event Bus で実装してみました。
(EventBusは便利で導入も容易ですが、若干古いかもしれないですね...)
ソースの主要な部分を以下に掲載します。
class App : Application(), LifecycleObserver {
companion object {
const val TAG = "App"
}
override fun onCreate() {
super.onCreate()
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreateLifecycle() {
// 最初の1回のみ
Log.d(TAG, "ON_CREATE")
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStartLifecycle() {
// アプリ開始時 or バックグラウンドからの復帰時
Log.d(TAG, "ON_START")
EventBus.getDefault().post(AppForegroundMessage())
}
/// 以下、省略
}
abstract class BaseActivity : AppCompatActivity() {
private val forceVersionUpLogic =
ForceVersionUpLogic()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onResume() {
super.onResume()
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}
@Subscribe
fun onReceiveMessage(eventMessage: AppForegroundMessage) {
ApiManager.service.getVersionJson().enqueue(object :
Callback<VersionModel> {
override fun onFailure(call: Call<VersionModel>, t: Throwable) {
Log.d(
"AppForegroundMessage",
"ApiManager.service.getVersionJson() onFailure",
t
)
}
override fun onResponse(call: Call<VersionModel>, response: Response<VersionModel>) {
response.body()?.let {
if (forceVersionUpLogic.checkForceVersionUp(it.version,
BuildConfig.VERSION_NAME
)) {
AlertDialog.Builder(this@BaseActivity)
.setTitle("アップデート")
.setMessage("アプリストアで最新のアプリをインストールしてください")
.setPositiveButton("ストアへ") { _, _ ->
// https://developer.android.com/distribute/marketing-tools/linking-to-google-play?hl=ja
val intent = Intent(
Intent.ACTION_VIEW
).apply {
data =
Uri.parse("https://play.google.com/store/apps/details?id=${BuildConfig.APPLICATION_ID}")
}
startActivity(intent)
}
.show()
}
}
}
})
}
}
設計としては単純ですが、アプリ起動・フォアグラウンド復帰時はダイアログが表示されました。
MainActivity <-> SubActivity の Activity遷移時はダイアログは表示されませんでした。
MVVMなどの組み合わせが要検証ですが、Activityを複数使う場合の手段になると思います。
まとめ
ProcessLifeCycleOwnerを使うことで、
ActivityのOnResumeでのアプリ復帰処理ではないところでイベントのハンドリングができるようになります。
アプリ起動時に通信をする場合などはちょっとタイミングの調整が必要そうですが、
今後はこちらで実装を進めるのが良いと思います。
追伸
最近、見つけたのですが、こちらも良記事です。
【Android】ライフサイクル(Lifecycle)アンチパターン 〜2020年版〜