简体   繁体   中英

How do I create a root launcher Activity in an app, when onCreate() is not called on Android 12, API 31?

I want to create an Android app which has a specific Activity that acts as a 'Root Launcher Activity' , to sometimes launch other Activities in the app. When this Root Launcher Activity starts, it will check a preference to see if it can directly launch a different Activity.

For many years on Android 11 (API 30) and below, this worked fine:

LoginActivity.kt

/** This is the main entry point of the app, when the user clicks the app icon. */
class LoginActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // If the user is already logged in, don't show the Login screen.
    // Instead proceed directly to the Welcome screen.
    val prefs = PreferenceManager.getDefaultSharedPreferences(this)
    val userIsLoggedIn = prefs.getBoolean("USER_IS_LOGGED_IN", false)
    if (userIsLoggedIn) {
      launchWelcomeScreenActivity()
      finish() // Close LoginActivity
    } else {
      displayLoginFields()
    }
  }

  override fun onResume() {
    super.onResume()
    Log.d("MyApp", "onResume()")
    // Nothing to do here
  }
  ...
}

AndroidManifest.xml

...
<application
  android:icon="@drawable/app_icon">
  <activity
    android:name=".LoginActivity"
    android:exported="true">
    <!-- This Activity is the main entry point to the app. Create an app icon for it. -->
    <intent-filter>
      <action android:name="android.intent.action.MAIN"/>
      <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
  </activity>
  ...
</application>
...

Now suppose that the user clicks a "Log Out" button on the WelcomeScreenActivity . It should log the user out, but remain on that screen with an image displayed:

class WelcomeScreenActivity : AppCompatActivity() {
  fun onLogoutClicked() {
    // Clear the logged in state and display an image
    val prefs = PreferenceManager.getDefaultSharedPreferences(this)
    prefs.edit().putBoolean("USER_IS_LOGGED_IN", false).apply()
    showLoggedOutImage()
  }
}

When the user presses the Back button, they will exit out of the app, because WelcomeScreenActivity is the only one left on the stack.

But now the problem is on Android 12 and above: When the user relaunches the app by clicking on the app icon, it will launch LoginActivity.onResume() and show the wrong screen. It's because LoginActivity.onCreate() is no longer called in this situation, due to the Activity lifecycle behavior changes, for Android 12/13 , quoted below:

Root launcher activities are no longer finished on Back press.

Android 12 changes the default handling of the system Back press on launcher activities that are at the root of their tasks. In previous versions, the system would finish these activities on Back press. In Android 12, the system now moves the activity and its task to the background instead of finishing the activity. The new behavior matches the current behavior when navigating out of an app using the Home button or gesture.

What I wanted and expected is that it should launch LoginActivity.onCreate() and call displayLoginFields() , just like on Android 11 and below. There is no obvious way to make the LoginActivity restart from a fresh state after the Back button exit, on Android 12.

So what is the correct way to handle this logic for a root launcher to work on all Android OS versions?

  1. Should I move the launcher code from onCreate() into onResume() or onNewIntent() ? Will this have any side-effects?
  2. Should I check if the app is running on Android 12 in onResume() , and use specific behavior for it, something like this:
/** This is the main entry point of the app, when the user clicks the app icon. */
class LoginActivity : AppCompatActivity() {
  ...
  override fun onResume() {
    super.onResume()
    val ANDROID_12_API_31 = 31
    if (Build.VERSION.SDK_INT >= ANDROID_12_API_31) {
      // Add the Activity launcher code from onCreate()
    }
  }
  ...
}
  1. Is there a way on Android 12 to force LoginActivity.onCreate() to be called after a relaunch from the Back button press?

Similar/related question, but not quite the same problem: How to set the root of the navigation stack

Note that Android 12 was released in October 2021 .

Why not just override onBackPressed() so that it finishes the Activity rather than calling super.onBackPressed() ? Then the old Back button behavior will be restored.

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