我想创建一个具有特定活动的Android应用程序,该应用程序充当“根启动器活动” ,有时在应用程序中启动其他活动。当此根启动器活动开始时,它将检查一个偏好,以查看是否可以直接启动其他活动。
多年在Android 11(API 30)及以下,这效果很好:
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>
...
strong 现在,用户单击“登录” “ westerescreenactivity
上的按钮。它应该将用户登录,但请保留在该屏幕上显示图像:
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()
}
}
当用户按下后按钮时,他们将退出应用程序,因为 weelcomescreenactivity
是堆栈上唯一剩下的一个。
但是现在问题在Android 12及更高版本上:当用户单击应用程序图标通过重新启动应用程序时,它将启动 loginActivity.onresume()
并显示错误的屏幕。这是因为 loginactivity.oncreate()
在这种情况下不再被调用,因为活动生命周期行为发生变化,适用于Android 12/13 ,下面引用:
根启动器活动不再在后压完成。
Android 12更改了系统背面对其任务根源的启动器活动的默认处理。在以前的版本中,该系统将在反印刷中完成这些活动。在Android 12中,系统现在将活动及其任务移至背景,而不是完成活动。使用主页或手势从应用程序导航时,新行为与当前行为匹配。
我想要和期望的是,它应该启动 loginActivity.oncreate.oncreate()
和call DisplayLoginfields()
,就像在Android 11及以下一样。没有明显的方法可以使 loginActivity
在Android 12上的后退按钮退出后重新启动新的状态。
因此,处理此逻辑的正确方法是什么供root Launcher来处理所有Android OS版本?
- 我是否应该将启动器代码从
ongreate()
将其移动到 onresume()或 onnewintent()
?这会有任何副作用吗?
- 我是否应该检查该应用在
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()
}
}
...
}
- Android 12上有办法强制
loginActivity.oncreate(Concreate)( )
在从后按钮重新启动后要调用?
相似/相关的问题,但不是完全相同的问题:设置导航堆栈的根源
请注意,Android 12是于2021年10月于2021年10月发布a>。
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?
- Should I move the launcher code from
onCreate()
into onResume()
or onNewIntent()
? Will this have any side-effects?
- 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()
}
}
...
}
- 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.
发布评论
评论(1)
为什么不覆盖
onbackPressed()
,以便完成活动
而不是调用super.onbackpressed()
?然后,将恢复旧的后退按钮行为。Why not just override
onBackPressed()
so that it finishes theActivity
rather than callingsuper.onBackPressed()
? Then the old Back button behavior will be restored.