首页 > 解决方案 > 当启动严格模式并将 `android:persistent` 设置为 `true` 时会出错。我该如何解决这个错误?

问题描述

当启动严格模式并设置android:persistenttruewill 有错误。我该如何解决这个错误?谢谢。

应用

override fun onCreate() {
    if (BuildConfig.DEBUG) {
        setStrictMode()
    }
    super.onCreate()
}

private fun setStrictMode() {
    StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
            .detectDiskReads()
            .detectDiskWrites()
            .detectNetwork()   // or .detectAll() for all detectable problems
            .penaltyLog()
            .build())
    StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder()
            .detectLeakedSqlLiteObjects()
            .detectLeakedClosableObjects()
            .penaltyLog()
            .penaltyDeath()
            .build())
}

偏好示例.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

        <SwitchPreference
            android:key="switch_preference_night_mode"
            android:persistent="true"
            android:title="@string/theme_settings_night_mode" />

</PreferenceScreen>

偏好片段:

public class ThemeSettingsFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.preference_example, rootKey);
    }
}

错误日志:

StrictMode: StrictMode policy violation; ~duration=30 ms: android.os.strictmode.DiskReadViolation
        at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1500)
        at java.io.UnixFileSystem.checkAccess(UnixFileSystem.java:251)
        at java.io.File.exists(File.java:815)
        at android.app.ContextImpl.getDataDir(ContextImpl.java:2237)
        at android.app.ContextImpl.getPreferencesDir(ContextImpl.java:550)
        at android.app.ContextImpl.getSharedPreferencesPath(ContextImpl.java:747)
        at android.app.ContextImpl.getSharedPreferences(ContextImpl.java:400)
        at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:174)
        at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:174)
        at android.support.v7.preference.PreferenceManager.getSharedPreferences(PreferenceManager.java:330)

标签: androidkotlinandroid-preferencesandroid-strictmode

解决方案


SharedPreferences第一次访问它们时从磁盘读取,然后缓存在内存中,因此您DiskReadViolation处于严格模式。

虽然将所有 I/O 作为非阻塞主线程运行是理想的,但即使您在 Google Apps 上启用严格模式,您也会在应用启动时看到红色闪烁,因此您可能无法轻松绕过您的严格模式违反。

您需要关注的主要事情是长时间运行的 HTTP 请求或在主线程上运行的长时间运行的数据库操作 - 这些都是要避免的,解决方案涉及使用AsyncTaskRxJava 或 Kotlin 协程之类的东西。

目前,theSharedPreference和相关setPreferenceFromResource的操作模式是您无法控制的,因此您不太可能通过围绕这些操作添加异步代码来使事情变得更好。


推荐阅读