我有若干与launchMode SingleInstance有关的活动。注销后,我要完成所有活动并打开launchScreen。
val intent = Intent(context, LauncherActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
(context as AppCompatActivity).finishAffinity()
context.startActivity(intent)
但是,如果我在启动器活动上按回去,则会被转发到以前使用singleInstance模式启动的活动
答案 0 :(得分:5)
我已经测试了多种方法来处理它,例如事件传播,意图标志,计数活动实例等。存在一些奇怪的情况,例如顺序启动多个singleInstance
活动。在这种情况下,中间活动根本不会启动(未调用onCreate
方法),并且在按返回按钮之后,它们将被启动。因此,任何一种先前的方法都行不通!由于这个问题有点奇怪,我试图用一种奇怪的方式解决它。
我们在名为LogoutHandler
的单例对象中维护注销状态。它与LogoutAwareActivity
以外的所有活动继承的类LoginActivity
合作,因为它不受注销机制的影响。注销发生时,在LogoutHandler
中设置一个标志,直到LogoutAwareActivity
的最后一个子项结束,然后清除该标志。
这是一个实现:
LogoutHandler:
import java.util.*
object LogoutHandler {
private var isLogout = false
private var timerWatchDog: TimerWatchDog? = null
fun isLogout() = isLogout
fun onActivityDestroyed() {
if (isLogout) {
timerWatchDog?.refresh(Runnable {
isLogout = false
timerWatchDog = null
})
}
}
fun logout() {
isLogout = true
timerWatchDog = TimerWatchDog(500)
}
private class TimerWatchDog(private val delay: Long) : Runnable {
private var timer: Timer? = null
private var runnable: Runnable? = null
fun refresh(runnable: Runnable) {
this.runnable = runnable
timer?.cancel()
val timerTask = object : TimerTask() {
override fun run() {
Thread(this@TimerWatchDog).start()
}
}
timer = Timer()
timer?.schedule(timerTask, delay)
}
override fun run() {
runnable?.run()
}
}
}
LogoutAwareActivity:
import android.support.v7.app.AppCompatActivity
abstract class LogoutAwareActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
if (LogoutHandler.isLogout()) {
finish()
}
}
override fun onDestroy() {
super.onDestroy()
LoginHandler.onActivityDestroyed()
}
}
具体活动:
class ActivityA : LogoutAwareActivity() {
// ...
}
另一项具体活动:
class ActivityB : LogoutAwareActivity() {
// ...
}
您的注销功能:
fun logout() {
val intent = Intent(context, LoginActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
LogoutHandler.logout()
context.startActivity(intent)
}
视觉结果:
MainActivity
,ActivityA
,ActivityB
和ActivityC
都是单个实例。
通过按返回按钮在活动之间进行遍历:
转到LoginActivity
,然后按返回按钮:
答案 1 :(得分:2)
我不知道您到底想做什么,但我有种感觉,您可以以不同的方式重新设计您的应用程序,从而做得更好。
无论如何,我想您是否可以注销活动,如果用户已经注销,以及他是否确实启动了单个实例启动器活动并使用finish()
关闭了这些活动,那么您可以检查活动的onStart。
答案 2 :(得分:2)
在启动初始屏幕之前,添加此行
ActivityCompat.finishAffinity(this)
答案 3 :(得分:1)
我有若干与launchMode SingleInstance有关的活动。注销后,我要完成所有活动并打开launchScreen。
这是一种方法:
BaseActivity
。finish()
。 BaseActivity
,因此将调用侦听器并结束活动。LauncherActivity
。请参见How to use LocalBroadcastManager? 更多。
P.S:您可以在onDestroy
中取消注册侦听器。由于活动仍然存在,因此不会调用onDestroy。而且,如果它已经被销毁了,那么您就不用担心其他活动了。
答案 4 :(得分:1)
以我的经验,扩展Application类是存储需要在所有活动之间共享的有限数据量的更简单,最有效的方法。
在您的情况下,您可以创建一个保存登录数据的类,并将其实例存储在您的自定义Application对象中,所有活动都可以在该对象中进行访问。他们可以在开始时检查登录可用性,订阅更改并在需要完成时得到通知。如果需要,Application对象本身可以订阅更改并启动登录活动。