简体   繁体   中英

Is there any way to distinguish between an Android Activity onResume from the home screen?

Is there any way to tell whether an Activity is being resumed (ie onResume is called) from the home screen/launcher?

For example, if I have an Application with two activities, A and B.

Scenario 1: Some user action on Activity A will invoke Activity B, bringing it into the foreground - moving Activity A into the background. As Activity A moves into the background, it goes through onPause() and onStop(). The user (now on Activity B) either finishes the Activity or hits the "back" button, bringing Activity A back to the foreground, causing an onRestart(), onStart(), onResume() sequence.

Scenario 2: If the user hits the "home" button while Activity A is in the foreground and then re-invokes the Application from the launcher, it goes through the same lifecycle as in Scenario 1. Ie User hits the "home" button. Activity goes through onPause() and onStop(). User launches the application again, causing Activity A go come back into the foreground, again going through the same onRestart(), onStart(), onResume() sequence as in Scenario 1.

As far as I can tell, the Activity has no way of knowing how it was resumed, it just knows it is being brought back into view. In fact, I have a feeling that there isn't really as much of a concept of an "Application" in Android - in the sense of something that has a single entry and exit point.

您可以捕获在活动B上按下后退按钮,并将一个额外的值传递给活动A。如果有一个额外的值,那么该活动是从在活动B上按回该活动而恢复的;如果没有额外的值,那么该活动将从被恢复的活动中恢复。隐。

在方案2中,您的活动将收到一个onNewIntent调用,并将启动器意图传递给它。

活动性A是否可以使用startActivityForResult()启动活动B,并使用onActivityResult()检测活动B是否完成?

So the straightforward answer to the initial question is probably: no. Launching an activity from the home screen through an icon, or resuming it from the recents screen can not be observed from the intent it is (re)started/resumed with.

Depending on what you are trying to achieve there are some approaches though:

  1. what @superfell suggested:

Check for whether the onNewIntent -method is called on your activity to decide if it was restarted from the launcher. As a precondition you need to set your activity to singleTask/singleTop launchMode in your Manifest:

android:launchMode="singleTask"

depending on what you're trying to achieve, this might be enough! But additionally you might have to deal with what happens when the user presses the back button. Default behavior is to finish & destroy your activity. Thus a brand new copy of it would be launched when it gets selected from the recents screen. Though onNewIntent would not be called, everything would be rebuilt from scratch. If you need to prevent this you can use:

override fun onBackPressed() {
    moveTaskToBack(true)
}

finally when you navigate "back" from an activity you launched yourself onNewIntent will also not be called. If you further need to distinguish why your activity is resumed, you might want to start the 2nd activity with startActivityForResult so the onActivityResult is called when you get resumed.

  1. Launcher activity & Intent extra

A completely different approach would be to have a "launcher" activity in your manifest that directly calls your "main" activity and finishes itself. When calling your main activity you can put an intent extra that allows your main activity to distinguish if it was just launched for the first time, or not. As the extra would be present on further onResumes, make sure to overwrite it the first time you "consume" it:

override fun onResume() {
    super.onResume()
    val firstLaunch = intent.getBooleanExtra(FIRST_LAUNCH, false)
    intent.putExtra(FIRST_LAUNCH,  false)
    if (firstLaunch) {
      // do something
    }
}

and when starting from your "launcher" activity:

intent.putExtra(FIRST_LAUNCH, true)
startActivity(intent)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM