Android BitmapFactory.decodeFile with intermittent null return

I am using android 4.0.4, kernel 3.0.8 +

Each so often, BitmapFactory.decodeFile returns a null bitmap.

Please note that if the factory bitmap does not load the bitmap, I will immediately try again, up to 4 times, and this often works (!)

There are many people who complain about this. Most questions have answers related to the placement of the bitmap, or to the nature of the stream of the discarded input stream / http / independently. I solved it - in fact, I reduced my problem to an android application of such ridiculous simplicity that it could be called a test case.

My application has one action, which contains one button, which, when pressed, launches a stream that goes through the directory of external files, trying to load everything into it in bitmap images. I do not use a bitmap, or hold it, or something else, I just load and forget:

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; } } } } 

I will see the output as follows:

 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 

In the above code, you will see a commented out alternative loading sequence in which, instead of using decodeFile, I load the file in bytes [], and then use decodeByteArray. This has the same effect (decodeByteArray fails, and then immediately gets exactly in one byte array!), But I note that errors are much less common.

In the case of decodeFile, possibly 1 out of 10 attempts returns null. In the case of decodeByteArray, perhaps only 1 out of 100. Not always the same file fails, but some files seem to fail more often than others.

My best guess is that the png decoder is crashing, which is most likely to happen if it works for a longer period of time, but after that I am a bit lost. If anyone has any light to get rid of the problem or alternative approaches to downloading png files, I would really appreciate it!

+7
android bitmap
source share
2 answers

Further experiments show that this happens on every device that I have (I have quite a lot), which has a special flavor 4.0.4, but does not occur even if it is left overnight on the device 4.1.1. Given the simplicity of the code, and that a later version of Android does not replicate it, my tendency is to flag this as a bug in Android that was fixed at some point. With this information, to help, I'm going to suggest that this is an error in SKIA, which is referred to here about the nth degree in this thread:

http://code.google.com/p/android/issues/detail?id=6066

My general opinion is that this is a rare mistake, the existence of which is obscured by a huge number of people who do not sufficiently process their input streams. The only answer I've seen anywhere for this problem is to try loading the bitmap in a loop (OMG). However, if hundreds of people who find this question because they have these symptoms could make them 100% sure that they are using a viable stream with a flushed stream before resorting to such an unholy hacking, then I think that we are all appreciate it!

thanks

PS Is it normal to feel guilty of calling this an β€œanswer”?

+2
source share

My problem was similar, but I solved it simply by adding permissions to access external storage:

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

Hope this helps.

0
source share

All Articles