Доступ к доступе к ShareDPreferences сделать с нитки UI?
-
09-10-2019 - |
Вопрос
С выпуском пряника я экспериментировал с некоторыми из новых 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);
Шаги объяснили:
- Основная деятельность вызывает GetLocalPreferences (this) -> Это прочитает ваши предпочтения, установите объект фильтра в классе вашего приложения и возвращает его.
- Когда вы вызываете функцию GetLocalPreferences () снова где-то еще в приложении, он сначала проверяет, если он недоступен в классе приложений, который намного быстрее.
ПРИМЕЧАНИЕ. Всегда проверяйте, отличается ли широкая переменная приложения от NULL, причина -> http://www.developerphil.com/dont-store-data-in-the-Application-Object/
Объект приложения не останется в памяти навсегда, он будет убит. Вопреки распространенному убеждению, приложение не будет перезапущено с нуля. Android создаст новый объект приложения и начать активность, когда пользователь должен был дать иллюзию, что приложение никогда не убило в первую очередь.
Если бы я не проверил на NULL, я позволил, чтобы нулевой столб был брошен при вызове, например, getmaxdistance () на объекте фильтра (если объект приложения был пронзен из памяти Android)