Android Handler Looper 深色主题行为

Android Handler Looper Dark Theme behavior

我在 Handler(Looper.getMainLooper()) 中遇到了有趣的行为。如果我的应用程序主题 (day/night) 设置为不同于 OS 设置,它会执行两次。例如,如果在设备设置中关闭深色模式并且我的应用程序 MainActivity 应用深色主题,那么 MainActivity 会启动两次。我没有找到任何关于为什么会发生的解释。

SplashActivity很简单

class SplashActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.splash_screen_layout)

        Handler(Looper.getMainLooper()).postDelayed({
            val intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
            Log.i("SPLASH","Main activity started")
            finish()
        }, 2000)
    }

}

Main Activity 有以下功能来检查应用程序设置中保存的主题并应用它:

函数

private fun checkDarkMode(){
        when (MainSettings(this).darkMode) {
            0 -> {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
                delegate.applyDayNight()
            }
            1 -> {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
                delegate.applyDayNight()
            }
            2 -> {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
                delegate.applyDayNight()
            }
        }
    }

因此,如果在设备设置中关闭暗模式,那么处理程序代码将为 AppCompatDelegate.MODE_NIGHT_YES 执行两次,而对于其他人则按预期执行一次。

反之亦然,如果设备处于关闭状态,则代码会执行两次 AppCompatDelegate.MODE_NIGHT_NO。

正如我所说,我没有找到任何解释或解决方案,所以我所做的只是将处理程序定义为 val,并在 onPause 或 onDestroy 的 SplashActivity

中取消了它的所有内容
private val handler = Handler(Looper.getMainLooper())

override fun onPause() {
        super.onPause()
        handler.removeCallbacksAndMessages(null)
    }

所以我的问题是为什么会发生这种情况,还有其他方法可以避免这种情况吗?

我会看一下 AppCompatDelegate 的源代码,它是 here(在第 201 行附近为它重新创建 activity 的部分做了很多工作)。

我无法为您的问题提供直接的解决方案,但另一种方法是仅继承 DayNight 主题之一(尽管您确实无法在下面的任何内容上使用夜间主题 Android 10,但在我看来这让事情变得容易多了)。

编辑:您可以在 Application class 中执行您的 checkDarkMode 方法,这应该有望在创建任何活动之前设置正确的模式(从而避免它们被更改时再次创建)。

public class MyApplication extends Application {

public void onCreate() {
    super.onCreate();
    checkDarkMode()
}