在使用StrictMode时,发现会爆出

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

 这个提示显示, 在UI线程中有IO操作,请这是尽量避免。

但是我们真的在UI线程中使用了吗?其实我们也是按照普通大众的方法调用的。 直接在UI线程中调用getSharedPreference方法,该方法可能就会产生IO操作。

跟着查一下源码吧.

在2.3版本中有这样的代码:

 @Override
public SharedPreferences getSharedPreferences(String name, int mode) {
SharedPreferencesImpl sp;
File f = getSharedPrefsFile(name);
synchronized (sSharedPrefs) {
sp = sSharedPrefs.get(f);
if (sp != null && !sp.hasFileChanged()) {
//Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
return sp;
}
} FileInputStream str = null;
File backup = makeBackupFile(f);
if (backup.exists()) {
f.delete();
backup.renameTo(f);
} // Debugging
if (f.exists() && !f.canRead()) {
Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
} Map map = null;
if (f.exists() && f.canRead()) {
try {
str = new FileInputStream(f);
map = XmlUtils.readMapXml(str);
str.close();
} catch (org.xmlpull.v1.XmlPullParserException e) {
Log.w(TAG, "getSharedPreferences", e);
} catch (FileNotFoundException e) {
Log.w(TAG, "getSharedPreferences", e);
} catch (IOException e) {
Log.w(TAG, "getSharedPreferences", e);
}
} synchronized (sSharedPrefs) {
if (sp != null) {
//Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
sp.replace(map);
} else {
sp = sSharedPrefs.get(f);
if (sp == null) {
sp = new SharedPreferencesImpl(f, mode, map);
sSharedPrefs.put(f, sp);
}
}
return sp;
}
}

看发生了xml的读写操作, 怪不得会有IO操作。

但是再4.0版本此处代码发生了变化。

 @Override
public SharedPreferences getSharedPreferences(String name, int mode) {
SharedPreferencesImpl sp;
synchronized (ContextImpl.class) {
if (sSharedPrefs == null) {
sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>();
} final String packageName = getPackageName();
ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
if (packagePrefs == null) {
packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
sSharedPrefs.put(packageName, packagePrefs);
} // At least one application in the world actually passes in a null
// name. This happened to work because when we generated the file name
// we would stringify it to "null.xml". Nice.
if (mPackageInfo.getApplicationInfo().targetSdkVersion <
Build.VERSION_CODES.KITKAT) {
if (name == null) {
name = "null";
}
} sp = packagePrefs.get(name);
if (sp == null) {
File prefsFile = getSharedPrefsFile(name);
sp = new SharedPreferencesImpl(prefsFile, mode);
packagePrefs.put(name, sp);
return sp;
}
}
if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
// If somebody else (some other process) changed the prefs
// file behind our back, we reload it. This has been the
// historical (if undocumented) behavior.
sp.startReloadIfChangedUnexpectedly();
}
return sp;
}

看代码,这里没看到XML的IO操作。 那这个IO跑哪里去了呢? 跟踪一下SharedPreferencesImpl的构造方法,

    SharedPreferencesImpl(File file, int mode) {
mFile = file;
mBackupFile = makeBackupFile(file);
mMode = mode;
mLoaded = false;
mMap = null;
startLoadFromDisk();
} private void startLoadFromDisk() {
synchronized (this) {
mLoaded = false;
}
new Thread("SharedPreferencesImpl-load") {
public void run() {
synchronized (SharedPreferencesImpl.this) {
loadFromDiskLocked();
}
}
}.start();
}

你看, XML的读取确实启动新线程了,那为什么还要爆出IO操作呢?   重新跟踪堆栈,发现原来不是这段代码发生的IO操作,是在startReloadIfChangedUnexpectedly中发生的, 代码中有些, 处于多进程模式,或者targe版本较低版本都会走该方法。那该方法中就会有IO操作。

后面, 我又更改了targetAPI的版本,不会走到startReloadIfChangedUnexpectedly中去。 果然StrictMode不会再查出东西来了。

最新文章

  1. 在C#代码中应用Log4Net(四)在Winform和Web中捕获全局异常
  2. SQLServer数据库转换成MySQL数据库
  3. WinCE项目应用之虚拟仪器(VI)
  4. ArcGIS 设置地图显示范围大小(全屏显示)
  5. 图解 &amp; 深入浅出JavaWeb:事务必会必知
  6. delegate基于on
  7. js部分---函数与递归;
  8. POJ 3177 Redundant Paths(Tarjan)
  9. 关于解决 The processing instruction target matching &quot;[xX][mM][lL]&quot; is not allowed
  10. C++为QLabel增加单击事件
  11. 纯css 构造的tip
  12. PHP中的数据结构
  13. 【第十九篇】laydate设置起始时间,laydate设置开始时间和结束时间
  14. python中MySQLdb的使用
  15. JAVA二分搜索树
  16. teleport使用说明
  17. GoldenGate实时投递数据到大数据平台(1)-MongoDB
  18. 解决最近vs2017总是在加载工程的时候卡住不不动
  19. smartsvn学习(二)如何在Xcode下使用SVN
  20. HighCharts设置图表背景透明

热门文章

  1. DebugDiag收集Dump的使用说明
  2. 日期转换工具类 CommUtil.java
  3. azure 云上MySQL最新版本 MySQL5.7.11 批量自动化一键式安装 (转)
  4. linux创建git远程仓库
  5. Hibernate3.3用户手册摘要-1-辅助类,session
  6. Neutron GRE模式要注意的问题
  7. phpinfo详解
  8. Centos7和win7双系统调整默认启动
  9. [内核同步]自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析
  10. ORACLE Instant Client 配置