При запуске строгого режима и установке `android:persistent` в`true` произойдет ошибка. Как я могу исправить эту ошибку?

Когда запустить строгий режим и установить android:persistent в true Воля имеет ошибку. Как я могу исправить эту ошибку? Благодарю.

заявка

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())
}

preference_example.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>

PreferenceFragment:

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)

2 ответа

Решение

SharedPreferences читаются с диска при первом обращении к ним и затем кэшируются в памяти, следовательно, ваш DiskReadViolation в строгом режиме.

Хотя запуск всех операций ввода-вывода, поскольку неблокирование основного потока, является идеальным, даже если вы включите строгий режим в Службах Google, вы увидите красные вспышки при запуске приложения, так что вы не сможете легко обойти свой строгий режим. нарушение.

Главное, что вас должно беспокоить - это длительные HTTP-запросы или длительные операции с базами данных, выполняющиеся в главном потоке - их следует избегать, а решения включают использование чего-то вроде AsyncTask, RxJava или Kotlin сопрограмм.

На данный момент, SharedPreference и связанный setPreferenceFromResource есть режимы работы, которые вы не контролируете, и поэтому вряд ли вы улучшите ситуацию, добавив асинхронный код вокруг них.

Я согласен с другим ответом, с этим ничего не поделаешь. Но это не должно мешать вам использовать его в других частях приложения. Чтобы игнорировать определенный путь кода изStrictMode, используйте этот шаблон:

          @Override
    public void onCreatePreferences(
            @Nullable Bundle savedInstanceState,
            @Nullable String rootKey
    ) {
        StrictMode.ThreadPolicy originalPolicy = StrictMode.allowThreadDiskReads();
        try {
            setPreferencesFromResource(R.xml.preferences, rootKey);
        } finally {
            StrictMode.setThreadPolicy(originalPolicy);
        }
    }
Другие вопросы по тегам