我使用的是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 情况下,可能十分之一的尝试会返回 null。在decodeByteArray 情况下,可能只有百分之一。失败的文件并不总是同一个,但有些文件确实失败seem比其他人更容易失败。
我最好的预感是 png 解码器出现故障,如果运行时间较长,则更有可能发生故障,但在那之后我有点迷失了。如果有人对这个问题有任何了解,或者有其他加载 png 文件的方法,我将非常感激!