简介
在分析优秀的第三方框架或者Android系统源码的时候,有时会发现一些鲜为人知的一些特殊处理,而这些处理平时也很少被开发者注意到。虽然测试的时候很难出现问题,但是一旦使用场景复杂后,难免会出问题。优秀的代码不仅是能够实现漂亮的功能,同时也得有很好的稳键性。这篇文章主要记录自己在分析第三方框架或者系统源码时候,遇到的一些不错的,但很少被人注意的处理。内容会持续更新。
realm数据库
Context.getFilesDir()返回null
在调用 Realm.init(context)初始化数据库的时候,会检查存储数据库文件的路径是否存在和有效。
/**
* In some cases, Context.getFilesDir() is not available when the app launches the first time.
* This should never happen according to the official Android documentation, but the race condition wasn't fixed
* until Android 4.4.
* <p>
* This method attempts to fix that situation. If this doesn't work an {@link IllegalStateException} will be
* thrown.
* <p>
* See these links for further details:
* https://issuetracker.google.com/issues/36918154
* https://github.com/realm/realm-java/issues/4493#issuecomment-295349044
*/
private static void checkFilesDirAvailable(Context context) {
File filesDir = context.getFilesDir();
if (filesDir != null) {
if (filesDir.exists()) {
return;
} else {
try {
filesDir.mkdirs();
} catch (SecurityException ignored) {
}
}
}
if (filesDir == null || !filesDir.exists()) {
// Wait a "reasonable" amount of time before quitting.
// In this case we define reasonable as 200 ms (~12 dropped frames) before giving up (which most likely
// will result in the app crashing). This lag would only be seen in worst case scenarios, and then, only
// when the app is started the first time.
long[] timeoutsMs = new long[]{1, 2, 5, 10, 16}; // Exponential waits, capped at 16 ms;
long maxTotalWaitMs = 200;
long currentTotalWaitMs = 0;
int waitIndex = -1;
while (context.getFilesDir() == null || !context.getFilesDir().exists()) {
long waitMs = timeoutsMs[Math.min(++waitIndex, timeoutsMs.length - 1)];
SystemClock.sleep(waitMs);
currentTotalWaitMs += waitMs;
if (currentTotalWaitMs > maxTotalWaitMs) {
break;
}
}
}
// One final check before giving up
if (context.getFilesDir() == null || !context.getFilesDir().exists()) {
throw new IllegalStateException("Context.getFilesDir() returns " + context.getFilesDir() + " which is not an existing directory. See https://issuetracker.google.com/issues/36918154");
}
}
方法上面的注释也告诉了可能出现的情况,注释里面的两个地址,都是关于Context.getFilesDir()返回null提给Google和realm的issue。
网友评论