Android 4.0.4、カーネル 3.0.8+ を使用しています
BitmapFactory.decodeFile が null ビットマップを返すことがよくあります。
ビットマップ ファクトリがビットマップの読み込みに失敗した場合は、すぐに最大 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 分の 1 です。失敗するのは常に同じファイルではありませんが、一部のファイルは他のファイルより頻繁に失敗するようです。
私の最良の予感は、png デコーダーには障害があり、長時間実行すると発生する可能性が高くなるということですが、その後は少し迷っています。誰かが問題に光を当てたり、pngファイルをロードする別の方法を持っていれば、本当に感謝しています!