我有几个使用launchMode SingleInstance 的 Activity 。注销时,我想完成所有 Activity 并打开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)

但是,如果我在 Launcher Activity 上按回,我将被转发到以前使用 singleInstance 模式启动的 Activity

最佳答案

2018 年 11 月 1 日更新:

我已经测试了多种方法来处理它,例如事件传播、 Intent 标志、计数 Activity 实例等。有一些奇怪的场景,例如顺序启动多个 singleInstance Activity 。在这种情况下,中间 Activity 根本不启动(不调用 onCreate 方法),按下后退按钮后,它们将启动。因此,之前的任何一种方法都不起作用!由于问题有点奇怪,我尝试使用有点奇怪的方法解决它。

我们在名为 LogoutHandler 的单例对象中维护注销状态。它与一个类 LogoutAwareActivity 合作,该类由除 LoginActivity 之外的所有 Activity 继承,因为它不应受到注销机制的影响。当注销发生时,在 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()
    }

}

一个具体的 Activity :
class ActivityA : LogoutAwareActivity() {

    // ...
}

另一个具体的 Activity :
class ActivityB : LogoutAwareActivity() {

    // ...
}

您的登出功能:
fun logout() {
    val intent = Intent(context, LoginActivity::class.java)
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

    LogoutHandler.logout()
    context.startActivity(intent)
}

视觉结果:
MainActivityActivityAActivityBActivityC 都是单实例。

通过按后退按钮在 Activity 之间遍历:

android - 如何完成多个 SingleInstance  Activity ?-LMLPHP

转到 LoginActivity 然后按后退按钮:

android - 如何完成多个 SingleInstance  Activity ?-LMLPHP

10-08 11:18