Android的BitmapFactory.de codeFILE间歇性地返回null [英] Android BitmapFactory.decodeFile intermittently returning null

查看:124
本文介绍了Android的BitmapFactory.de codeFILE间歇性地返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是安卓4.0.4,内核3.0.8 +

I'm using android 4.0.4, kernel 3.0.8+

每隔一段时间BitmapFactory.de codeFILE返回一个空的位图。

Every so often BitmapFactory.decodeFile returns a null bitmap.

请注意,如果位图的工厂无法加载位图我马上再试,高达4倍,这往往工作(!)

Note that if the bitmap factory fails to load the bitmap I immediately try again, up to 4 times, and this often works (!)

有很多人抱怨这一点。大部分的问题都涉及到答案所在的位图放,或刷新输入流/ HTTP连接/不管的性质。我已经排除这些了 - 其实,我已经减少了我的问题,以这种可笑的简单的Andr​​oid应用程序,它可以被称为一个测试用例

There are a lot of people complaining about this. Most of the questions have answers involving where the bitmap is put, or the nature of the flushed input stream / http connection / whatever. I have ruled these out - in fact, I have reduced my problem to an android application of such ridiculous simplicity that it could be called a test case.

我的应用程序有一个单一的活动,其中包含一个按钮,当按下启动一个线程,遍历外部文件目录尝试加载一切成位图。我不使用位图,或保持,或任何东西,我只是加载,忘记了:

My app has a single activity, which contains a single button, which when pushed starts a thread that loops through the external files directory trying to load everything in it into bitmaps. I don't use the bitmap, or keep it, or anything, 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 output like this:

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

您将在上述code看到有一个注释掉的替代负荷序列,其中,而不是使用德codeFILE我将文件加载到一个byte [],然后使用去codeByteArray。这有同样的效果(DE codeByteArray失败,然后立即成功完全相同的字节数组!),但我注意到,失败是不太常见。

You will see in the above code there is a commented out alternative load sequence, in which rather than using decodeFile I load the file into a byte[] and then use decodeByteArray. This has the same effect (decodeByteArray fails and then immediately succeeds on exactly the same byte array!), but I do note that the failures are much less common.

在德codeFILE的情况下,也许在10 1试图返回null。在德codeByteArray情况下,也许只有在100 1并不总是失败相同的文件,但一些文件做的似乎的更频繁地比别人失败。

In the decodeFile case, perhaps 1 in 10 attempts returns null. In the decodeByteArray case, perhaps only 1 in 100. It is not always the same file that fails, but some files do seem to fail more often than others.

我最好的预感是,巴新德codeR发生故障这样更容易,如果它运行在一个较长的时间段发生,但在那之后,我有点失落。如果任何人有任何光线阐明这个问题,或替代方法来加载PNG文件,我真的AP preciate了!

My best hunch is that the png decoder has a failure which is more likely to occur if it runs over a longer period of time, but after that I'm a bit lost. If anyone has any light to shed on the issue, or alternative approaches to loading png files, I'd really appreciate it!

推荐答案

进一步的实验表明,这种情况发生时每个设备予有(Ⅰ有相当多的),其运行的4.0.4一个特定的风味,但不会发生即使留下了4.1.1设备上运行过夜。鉴于在code简单,那以后的And​​r​​oid版本不复制它,我的倾向是,以纪念本作已在Android的一个bug,在某些时候,得到修复。有了这些信息的帮助,我会认为这是一个被争论到第n程度在这个线程在这里Skia的一个错误:

Further experiments show that this occurs on every device I have (I have quite a lot) which is running a particular flavour of 4.0.4, but does not occur even if left running overnight on a 4.1.1 device. Given the simplicity of the code, and that a later android version doesn't replicate it, my inclination is to mark this as a bug in Android which has, at some point, been fixed. With that information to help, I am going to assume that this is a bug in SKIA which is argued about to the nth degree in this thread here:

HTTP://$c$c.google。 COM / P /安卓/问题/详细信息?ID = 6066

我的总的看法是,这是一个很少出现的错误,这错误的存在是由人谁不处理他们的输入流足够仔细数量巨大遮蔽。我见过的任何地方的唯一答案的这个的问题是要尝试加载位图在一个循环(OMG)。但是,如果数百人谁找到这个问题,因为他们有这些的症状的可能诉诸这样一个邪恶的黑客攻击之前,请确保他们使用的是一种可行的刷新输入流100%的话,我想我们倒是所有的AP preciate了!

My overall opinion is that this is a rarely occurring bug the existence of which is obscured by the enormous number of people who don't handle their input streams carefully enough. The only answer I've seen anywhere for this problem is to attempt to load the bitmap in a loop (OMG). However, if the hundreds of people who find this question because they have these symptoms could please make 100% sure that they are using a viable flushed input stream before resorting to such an unholy hack, then I think we'd all appreciate it!

感谢

P.S。是否确定感到内疚调用这个一个答案?

P.S. is it OK to feel guilty about calling this an "answer" ?

这篇关于Android的BitmapFactory.de codeFILE间歇性地返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆