Вопрос

С выпуском пряника я экспериментировал с некоторыми из новых API, один из них Строгий.

Я заметил, что одна из предупреждений для getSharedPreferences().

Это предупреждение:

StrictMode policy violation; ~duration=1949 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=23 violation=2

и это дается для getSharedPreferences() Вызов быть сделанным на бите UI.

Должен SharedPreferences Доступ и изменения действительно сделаны с нитки UI?

Это было полезно?

Решение

Я рад, что ты уже играешь с этим!

Некоторые вещи следует обратить внимание: (в ленивой форме пули)

  • Если это худшее из ваших проблем, ваше приложение, вероятно, в хорошем месте. :) Пишетки, как правило, медленнее, чем чтение, однако, поэтому будьте уверены, что вы используете ShareDPreferections $ Editor.apply () вместо совершения (). Применить () - это новый в ГБ и Async (но всегда в безопасности, осторожны с переходами жизненного цикла). Вы можете использовать отражение с условно вызовами применить () на GB + и Commit () на Froyo или ниже. Я буду делать блогпост с образцем кода того, как это сделать.

Что касается нагрузки, хотя ...

  • После загрузки SharedPreference - это синглеты и кэшированные процессы. Таким образом, вы хотите загрузить его как можно раньше, так что у вас его в памяти, прежде чем вам это нужно. (Предполагая, что это мало, как и должно быть, если вы используете SharedPreferences, простой XML-файл ...) Вы не хотите ошибоваться в будущем в будущем, когда некоторые пользователь нажимают кнопку.

  • Но всякий раз, когда вы называете Context.getSharedPreferences (...), поддерживающий XML-файл является Stat'd, чтобы увидеть, изменятся ли он, поэтому вы захотите избежать этих статистиков во время мероприятий по интерфейсам интерфейса в любом случае. У статистики обычно должны быть быстрыми (и часто кэшироваться), но Yaffs не имеет большого способа параллелизма (и многие устройства Android работают на Yaffs ... Droid, Nexus One и т. Д.) Так, если вы избегаете диска , вы избегаете застревать за другими в полете или в ожидании дисковых операций.

  • Поэтому вы, вероятно, захотите загрузить ShareDPreferences во время вашего OnCreate () и повторно используйте тот же экземпляр, избегая стата.

  • Но если в любом случае, если вам не нужны ваши предпочтения во время OnCreate (), что время загрузки ненужно запускает ваше приложение, поэтому, как правило, лучше иметь что-то вроде футуретаскаu003CSharedPreferences> Подкласс, который начинает новую тему. Тогда просто найдите на вашу футуретаснуюu003CSharedPreferences> Член всякий раз, когда вам это нужно и .get () это. Я планирую сделать это свободно за кулисами в сотах, прозрачно. Я постараюсь выпустить какой-то пример код, который показывает лучшие практики в этой области.

Проверьте блог разработчиков Android для предстоящих сообщений на предметах, связанных с striThmode в предстоящие недели (ы).

Другие советы

Доступ к общим предпочтениям может занять некоторое время, потому что они читаются от флэш-памяти. Вы много читаете? Может быть, вы можете использовать другой формат, например, база данных SQLite.

Но не исправляйте все, что вы найдете с помощью StrictMode. Или процитировать документацию:

Но не чувствую себя вынужденным исправить все, что находит строговысокое. В частности, многие случаи доступа к диску часто необходимо во время жизненного цикла обычной активности. Используйте StrictMode, чтобы найти вещи, которые вы случайно. Сетевые запросы на ните UI почти всегда проблема.

Одна тонкость о ответе Брэда: даже если вы загружаете ShareDPreferences в OnCreate (), вы, вероятно, до сих пор до сих пор до сих пор будут читать значения на фоновом потоке, потому что GetString () и т. Д. Блок до тех пор, пока не прочитал общие предпочтения файла в отделке (на фоновом потоке):

public String getString(String key, String defValue) {
    synchronized (this) {
        awaitLoadedLocked();
        String v = (String)mMap.get(key);
        return v != null ? v : defValue;
    }
}

Редактировать () также блокировки таким же образом, хотя применить (), кажется, безопасен на ните переднего плана.

(Кстати, извините, чтобы положить это здесь. Я бы положил это как комментарий к ответу Брэда, но я только что присоединился и не хватает репутации, чтобы сделать это.)

Я знаю, что это старый вопрос, но я хочу поделиться своим подходом. У меня было длительное время чтения и использовали комбинацию общих предпочтений и глобального класса приложений:

ApplicationClass:

public class ApplicationClass extends Application {

    private LocalPreference.Filter filter;

    public LocalPreference.Filter getFilter() {
       return filter;
    }

    public void setFilter(LocalPreference.Filter filter) {
       this.filter = filter;
    }
}

LocalPreference:

public class LocalPreference {

    public static void saveLocalPreferences(Activity activity, int maxDistance, int minAge,
                                            int maxAge, boolean showMale, boolean showFemale) {

        Filter filter = new Filter();
        filter.setMaxDistance(maxDistance);
        filter.setMinAge(minAge);
        filter.setMaxAge(maxAge);
        filter.setShowMale(showMale);
        filter.setShowFemale(showFemale);

        BabysitApplication babysitApplication = (BabysitApplication) activity.getApplication();
        babysitApplication.setFilter(filter);

        SecurePreferences securePreferences = new SecurePreferences(activity.getApplicationContext());
        securePreferences.edit().putInt(Preference.FILER_MAX_DISTANCE.toString(), maxDistance).apply();
        securePreferences.edit().putInt(Preference.FILER_MIN_AGE.toString(), minAge).apply();
        securePreferences.edit().putInt(Preference.FILER_MAX_AGE.toString(), maxAge).apply();
        securePreferences.edit().putBoolean(Preference.FILER_SHOW_MALE.toString(), showMale).apply();
        securePreferences.edit().putBoolean(Preference.FILER_SHOW_FEMALE.toString(), showFemale).apply();
    }

    public static Filter getLocalPreferences(Activity activity) {

        BabysitApplication babysitApplication = (BabysitApplication) activity.getApplication();
        Filter applicationFilter = babysitApplication.getFilter();

        if (applicationFilter != null) {
            return applicationFilter;
        } else {
            Filter filter = new Filter();
            SecurePreferences securePreferences = new SecurePreferences(activity.getApplicationContext());
            filter.setMaxDistance(securePreferences.getInt(Preference.FILER_MAX_DISTANCE.toString(), 20));
            filter.setMinAge(securePreferences.getInt(Preference.FILER_MIN_AGE.toString(), 15));
            filter.setMaxAge(securePreferences.getInt(Preference.FILER_MAX_AGE.toString(), 50));
            filter.setShowMale(securePreferences.getBoolean(Preference.FILER_SHOW_MALE.toString(), true));
            filter.setShowFemale(securePreferences.getBoolean(Preference.FILER_SHOW_FEMALE.toString(), true));
            babysitApplication.setFilter(filter);
            return filter;
        }
    }

    public static class Filter {
        private int maxDistance;
        private int minAge;
        private int maxAge;
        private boolean showMale;
        private boolean showFemale;

        public int getMaxDistance() {
            return maxDistance;
        }

        public void setMaxDistance(int maxDistance) {
            this.maxDistance = maxDistance;
        }

        public int getMinAge() {
            return minAge;
        }

        public void setMinAge(int minAge) {
            this.minAge = minAge;
        }

        public int getMaxAge() {
            return maxAge;
        }

        public void setMaxAge(int maxAge) {
            this.maxAge = maxAge;
        }

        public boolean isShowMale() {
            return showMale;
        }

        public void setShowMale(boolean showMale) {
            this.showMale = showMale;
        }

        public boolean isShowFemale() {
            return showFemale;
        }

        public void setShowFemale(boolean showFemale) {
            this.showFemale = showFemale;
        }
    }

}

МАКСИВНОСТЬ (деятельность, которая вызывается в первую очередь в вашем приложении):

LocalPreference.getLocalPreferences(this);

Шаги объяснили:

  1. Основная деятельность вызывает GetLocalPreferences (this) -> Это прочитает ваши предпочтения, установите объект фильтра в классе вашего приложения и возвращает его.
  2. Когда вы вызываете функцию GetLocalPreferences () снова где-то еще в приложении, он сначала проверяет, если он недоступен в классе приложений, который намного быстрее.

ПРИМЕЧАНИЕ. Всегда проверяйте, отличается ли широкая переменная приложения от NULL, причина -> http://www.developerphil.com/dont-store-data-in-the-Application-Object/

Объект приложения не останется в памяти навсегда, он будет убит. Вопреки распространенному убеждению, приложение не будет перезапущено с нуля. Android создаст новый объект приложения и начать активность, когда пользователь должен был дать иллюзию, что приложение никогда не убило в первую очередь.

Если бы я не проверил на NULL, я позволил, чтобы нулевой столб был брошен при вызове, например, getmaxdistance () на объекте фильтра (если объект приложения был пронзен из памяти Android)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top