通过 Intent 从 activity A->B->C- 切换回 A 与多次调用 finish() 之间的区别
Difference between switching from activity A->B->C- back to A via Intent vs several calls to finish()
假设我有三个活动 A、B 和 C 用于以下方式。您从 activity A 开始,然后按一个按钮将您带到 B,然后再按另一个按钮将您带到 C。现在在 C 上你已经完成并想返回 A。可能有很多方法可以做到这一点,但我感兴趣的是通过 Intent 返回 A 与使用 之间的区别]完成().
使用意图:
Intent(this, A::class.java).also { startActivity(it) }
使用 finish(): 为了正确地回到 A,我相信我必须做这样的事情。
// Activity_B.kt
...
override fun onResume() {
super.onResume()
if(resumed > 0) { // resumed is "private var resumed: Int = 0"
// Next time we resume, we'll enter here.
// Specifically, we end up here after C calls finish()
finish() // This takes us back to activity A.
} else {
// End up here after first time A is created
resumed++
}
}
// Activity_C.kt
...
finish() // This takes us back to Activity_B and onResume() is called
...
使用 Intents 我们会立即在 A 中结束,而如果我们以第二种方式进行,我们必须先通过 B 返回.我的问题是一个是否比另一个更合适?出于某种原因,使用 finish() 的第二种方式感觉更自然,因为我们通过完成活动的使用回溯,而在使用意图时感觉就像我们“让活动等待和未完成“ 在某种意义上。在“幕后”的行为上真的有区别还是等同的?
如果我理解你的问题,我认为 finish() 只是调用当前 activity 的 finish() 方法。如果您想转到特定的 activity,意图是最好和合适的方法。当然有旗帜。
我不知道你为什么需要 OnResume()。
通常最好使用 startActivity(intent);然后调用 finish();这样当前的 activity 就不会留在后台。除非你当然想要那个。
ps。从 Java 的角度来谈谈这里。不知道在Kotlin里是不是一样
onButtonClick(View v){
Intent intent=new Intent(context,targetactivity.class);
// if you want put your Flags actions or Extras here...
//start target activity.
startActivity(intent);
// finish current activity
// this is just to finish the current activity and ha no control
// on where you end up.
finish()
}
并且可以覆盖 onBackPressed()
主要区别在于您在 back stack 中的最终结果。如果您使用意图返回 A
,您最终会得到 [A, B, C, A]
的返回堆栈,这意味着如果用户在执行此操作后按下 phone 上的后退按钮,他们将回到 C
。再次按回键会将它们带回 B
。根据这些活动是什么,这可能是也可能不是期望的行为。
如果您使用 finish()
,活动将从返回堆栈中删除,因此返回到 A
后,您的返回堆栈将不包括 B
和 C
,它只是 [A]
但是,您应该使用 onActivityResult
回调或在移动到 C 之前完成 B 而不是依赖 onResume
。使用 onResume
会产生意想不到的副作用,例如,如果用户在 Activity B 上最小化您的应用程序(例如查看他们的电子邮件或接听电话) - 当他们回到您的应用程序时,它会调用onResume
并错误地触发 finish()
。
方法一-Activity结果回调
这个流程是:
- ActivityA开始activityB
- Activity B 使用 appropriate
onActivityResult
callback 启动 activity C。在此回调中,activity B 将在通知 C
已完成时调用 finish()
。
- 当 activity C 完成时,它将其结果状态设置为完成 (
RESULT_OK
) 并调用 finish()
- 这将通知 activity B 它也必须致电 finish()
例如,这些将在 Activity B:
// Activity B
var goToC = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// This will be called when C is completed
finish();
}
}
private fun goToActivityC() {
val intent = Intent(this, ActivityC::class.java)
goToC.launch(intent)
}
当 activity C 完成时,您将调用此方法来设置其结果并自行完成(将应用程序带回 B 并立即触发上面的回调)。请注意,如果用户按回键,则不会设置结果,他们只会返回 B 而不会触发回调。
// Activity C
private fun allDone() {
Intent data = Intent()
setResult(Activity.RESULT_OK, data)
finish()
}
方法 2 - 在启动 C 之前完成 B
另一种替代方法是在开始 C 之前先完成 B,这样 Activity B 就会使用
private fun goToActivityC() {
val intent = Intent(this, ActivityC::class.java)
startActivity(intent)
finish() // finish and remove B from the back stack
// back stack will now be [A, C]
}
并在 Activity C
private fun allDone() {
finish() // finish and remove C from the back stack
// Will take you back to A and back stack will be just [A]
}
这种方法的主要缺点是,如果用户在 C 上按下返回键,他们将返回到 A,而不是 B。这可能不是直观的行为(实际上取决于这些活动是什么)。
假设我有三个活动 A、B 和 C 用于以下方式。您从 activity A 开始,然后按一个按钮将您带到 B,然后再按另一个按钮将您带到 C。现在在 C 上你已经完成并想返回 A。可能有很多方法可以做到这一点,但我感兴趣的是通过 Intent 返回 A 与使用 之间的区别]完成().
使用意图:
Intent(this, A::class.java).also { startActivity(it) }
使用 finish(): 为了正确地回到 A,我相信我必须做这样的事情。
// Activity_B.kt
...
override fun onResume() {
super.onResume()
if(resumed > 0) { // resumed is "private var resumed: Int = 0"
// Next time we resume, we'll enter here.
// Specifically, we end up here after C calls finish()
finish() // This takes us back to activity A.
} else {
// End up here after first time A is created
resumed++
}
}
// Activity_C.kt
...
finish() // This takes us back to Activity_B and onResume() is called
...
使用 Intents 我们会立即在 A 中结束,而如果我们以第二种方式进行,我们必须先通过 B 返回.我的问题是一个是否比另一个更合适?出于某种原因,使用 finish() 的第二种方式感觉更自然,因为我们通过完成活动的使用回溯,而在使用意图时感觉就像我们“让活动等待和未完成“ 在某种意义上。在“幕后”的行为上真的有区别还是等同的?
如果我理解你的问题,我认为 finish() 只是调用当前 activity 的 finish() 方法。如果您想转到特定的 activity,意图是最好和合适的方法。当然有旗帜。
我不知道你为什么需要 OnResume()。
通常最好使用 startActivity(intent);然后调用 finish();这样当前的 activity 就不会留在后台。除非你当然想要那个。
ps。从 Java 的角度来谈谈这里。不知道在Kotlin里是不是一样
onButtonClick(View v){
Intent intent=new Intent(context,targetactivity.class);
// if you want put your Flags actions or Extras here...
//start target activity.
startActivity(intent);
// finish current activity
// this is just to finish the current activity and ha no control
// on where you end up.
finish()
}
并且可以覆盖 onBackPressed()
主要区别在于您在 back stack 中的最终结果。如果您使用意图返回 A
,您最终会得到 [A, B, C, A]
的返回堆栈,这意味着如果用户在执行此操作后按下 phone 上的后退按钮,他们将回到 C
。再次按回键会将它们带回 B
。根据这些活动是什么,这可能是也可能不是期望的行为。
如果您使用 finish()
,活动将从返回堆栈中删除,因此返回到 A
后,您的返回堆栈将不包括 B
和 C
,它只是 [A]
但是,您应该使用 onActivityResult
回调或在移动到 C 之前完成 B 而不是依赖 onResume
。使用 onResume
会产生意想不到的副作用,例如,如果用户在 Activity B 上最小化您的应用程序(例如查看他们的电子邮件或接听电话) - 当他们回到您的应用程序时,它会调用onResume
并错误地触发 finish()
。
方法一-Activity结果回调
这个流程是:
- ActivityA开始activityB
- Activity B 使用 appropriate
onActivityResult
callback 启动 activity C。在此回调中,activity B 将在通知C
已完成时调用finish()
。 - 当 activity C 完成时,它将其结果状态设置为完成 (
RESULT_OK
) 并调用finish()
- 这将通知 activity B 它也必须致电finish()
例如,这些将在 Activity B:
// Activity B
var goToC = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// This will be called when C is completed
finish();
}
}
private fun goToActivityC() {
val intent = Intent(this, ActivityC::class.java)
goToC.launch(intent)
}
当 activity C 完成时,您将调用此方法来设置其结果并自行完成(将应用程序带回 B 并立即触发上面的回调)。请注意,如果用户按回键,则不会设置结果,他们只会返回 B 而不会触发回调。
// Activity C
private fun allDone() {
Intent data = Intent()
setResult(Activity.RESULT_OK, data)
finish()
}
方法 2 - 在启动 C 之前完成 B
另一种替代方法是在开始 C 之前先完成 B,这样 Activity B 就会使用
private fun goToActivityC() {
val intent = Intent(this, ActivityC::class.java)
startActivity(intent)
finish() // finish and remove B from the back stack
// back stack will now be [A, C]
}
并在 Activity C
private fun allDone() {
finish() // finish and remove C from the back stack
// Will take you back to A and back stack will be just [A]
}
这种方法的主要缺点是,如果用户在 C 上按下返回键,他们将返回到 A,而不是 B。这可能不是直观的行为(实际上取决于这些活动是什么)。