[英]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.我想创建一个具有特定 Activity 的 Android 应用程序,它充当'Root Launcher Activity' ,有时在应用程序中启动其他活动。 When this Root Launcher Activity starts, it will check a preference to see if it can directly launch a different Activity.
当这个 Root Launcher Activity 启动时,它会检查一个首选项,看它是否可以直接启动不同的 Activity。
For many years on Android 11 (API 30) and below, this worked fine:多年来,在 Android 11 (API 30) 及更低版本上运行良好:
LoginActivity.kt登录活动.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 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
.现在假设用户单击
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.当用户按下后退按钮时,他们将退出应用程序,因为
WelcomeScreenActivity
是堆栈中唯一剩下的一个。
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.但现在问题出现在 Android 12 及更高版本上:当用户通过单击应用图标重新启动应用时,它将启动
LoginActivity.onResume()
并显示错误的屏幕。 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:这是因为
LoginActivity.onCreate()
在这种情况下不再被调用,由于Activity 生命周期行为的变化,对于 Android 12/13 ,引用如下:
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.
Android 12 更改了系统对位于其任务根目录的启动器活动的后按的默认处理。 In previous versions, the system would finish these activities on Back press.
在以前的版本中,系统将在 Back press 上完成这些活动。 In Android 12, the system now moves the activity and its task to the background instead of finishing the activity.
在 Android 12 中,系统现在将 Activity 及其任务移至后台,而不是完成 Activity。 The new behavior matches the current behavior when navigating out of an app using the Home button or gesture.
使用 Home 按钮或手势离开应用程序时,新行为与当前行为相匹配。
What I wanted and expected is that it should launch LoginActivity.onCreate()
and call displayLoginFields()
, just like on Android 11 and below.我想要和期望的是它应该启动
LoginActivity.onCreate()
并调用displayLoginFields()
,就像在 Android 11 及更低版本上一样。 There is no obvious way to make the LoginActivity
restart from a fresh state after the Back button exit, on Android 12.在 Android 12 上,没有明显的方法可以在后退按钮退出后让
LoginActivity
状态重新启动。
So what is the correct way to handle this logic for a root launcher to work on all Android OS versions?那么处理这个逻辑的正确方法是什么,让 root 启动器可以在所有 Android 操作系统版本上运行呢?
onCreate()
into onResume()
or onNewIntent()
?onCreate()
移动到onResume()
还是onNewIntent()
? Will this have any side-effects?onResume()
, and use specific behavior for it, something like this:onResume()
中检查应用程序是否在 Android 12 上运行,并为其使用特定行为,如下所示:/** 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()
}
}
...
}
LoginActivity.onCreate()
to be called after a relaunch from the Back button press? LoginActivity.onCreate()
? 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 .请注意,Android 12 于 2021 年 10 月发布。
Why not just override onBackPressed()
so that it finishes the Activity
rather than calling super.onBackPressed()
?为什么不直接覆盖
onBackPressed()
以便它完成Activity
而不是调用super.onBackPressed()
? Then the old Back button behavior will be restored.然后将恢复旧的后退按钮行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.