我正在使用 android 4.0.4,内核 3.0.8+
每隔一段时间 BitmapFactory.decodeFile 返回一个空位图。
请注意,如果位图工厂无法加载位图,我会立即重试,最多 4 次,这通常有效(!)
有很多人抱怨这个。大多数问题的答案都涉及位图的放置位置,或者刷新的输入流/http 连接/其他的性质。我已经排除了这些——事实上,我已经将我的问题简化为一个简单到可以称为测试用例的 android 应用程序。
我的应用程序有一个活动,其中包含一个按钮,当按下该按钮时会启动一个线程,该线程循环通过外部文件目录尝试将其中的所有内容加载到位图中。我不使用位图,也不保留它,或者任何东西,我只是加载并忘记:
public class MainActivity extends Activity {
private static final String TAG = "bmpbash";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onGo(View view) {
view.setVisibility(View.GONE);
start();
}
/**
* Start the thread.
*/
public void start() {
Runnable r = new Runnable() {
@Override
public void run() {
mainLoop();
}
};
Thread thread = new Thread(r);
thread.start();
}
public void mainLoop() {
int index = 0;
File top = getExternalFilesDir(null);
while (true) {
File[] files = top.listFiles();
if (files.length < 1) {
Log.e(TAG, "no files found");
} else {
if (files.length <= index) {
index = 0;
}
File file = files[index];
//byte[] data = readFile(file);
try {
boolean ok = false;
for (int i = 0; i < 4 && !ok; ++i) {
//Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
if (bitmap == null) {
Log.e(TAG, file.getName() + "[" + i + "] - NULL bitmap");
} else {
ok = true;
Log.w(TAG, file.getName() + "[" + i + "] - OK");
}
}
} catch (Exception e) {
Log.e(TAG, file.getName() + " - DIED", e);
} catch (OutOfMemoryError oom) {
Log.e(TAG, file.getName() + " - OOM");
}
++index;
}
}
}
}
我会看到这样的输出:
10-22 17:27:57.688: W/bmpbash(1131): translucent.png[0] - OK
10-22 17:27:57.698: W/bmpbash(1131): fearthecow.png[0] - OK
10-22 17:27:57.798: W/bmpbash(1131): gui2.png[0] - OK
10-22 17:27:57.888: W/bmpbash(1131): gui.png[0] - OK
10-22 17:27:58.058: W/bmpbash(1131): boot.png[0] - OK
10-22 17:27:58.218: E/bmpbash(1131): trainer2.png[0] - NULL bitmap
10-22 17:27:58.378: W/bmpbash(1131): trainer2.png[1] - OK
您将在上面的代码中看到一个被注释掉的替代加载序列,在该序列中,我不使用 decodeFile,而是将文件加载到 byte[] 中,然后使用 decodeByteArray。这具有相同的效果(decodeByteArray 失败,然后立即在完全相同的字节数组上成功!),但我确实注意到失败并不常见。
在 decodeFile 的情况下,10 次尝试中可能有 1 次返回 null。在 decodeByteArray 的情况下,可能只有 100 分之一。失败的文件并不总是同一个文件,但某些文件似乎确实比其他文件更频繁地失败。
我最好的预感是 png 解码器出现故障,如果它运行较长时间,则更有可能发生故障,但在那之后我有点迷失了。如果有人对这个问题有任何看法,或者加载 png 文件的替代方法,我真的很感激!