- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 android 4.0.4,内核 3.0.8+
BitmapFactory.decodeFile 每隔一段时间就会返回一个空位图。
请注意,如果位图工厂加载位图失败,我会立即重试,最多 4 次,这通常有效(!)
有很多人提示这个。大多数问题的答案都涉及位图的放置位置,或者刷新输入流的性质/http 连接/等等。我已经排除了这些可能性 - 事实上,我已经将我的问题简化为一个 android 应用程序,它非常简单,可以称为测试用例。
我的应用程序只有一个 Activity ,其中包含一个按钮,按下该按钮会启动一个线程,该线程循环遍历外部文件目录,试图将其中的所有内容加载到位图中。我不使用位图,也不保留它或其他任何东西,我只是加载并忘记:
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 文件的其他方法有任何了解,我将不胜感激!
最佳答案
进一步的实验表明,这种情况发生在我拥有的每台设备上(我有很多)运行特定风格的 4.0.4,但即使在 4.1.1 设备上运行一夜也不会发生。鉴于代码的简单性,而且后来的 android 版本没有复制它,我倾向于将其标记为 Android 中的一个错误,该错误在某个时候已得到修复。有了这些信息的帮助,我将假设这是 SKIA 中的一个错误,在这里这个线程中争论到第 n 度:
http://code.google.com/p/android/issues/detail?id=6066
我的总体意见是,这是一个很少发生的错误,大量未足够仔细地处理其输入流的人掩盖了该错误的存在。对于这个 问题,我在任何地方看到的唯一答案是尝试在循环中加载位图 (OMG)。然而,如果因为有这些症状而发现这个问题的数百人在求助于这种邪恶的 hack 之前可以 100% 确定他们使用的是可行的刷新输入流,那么我认为我们都会感激不尽!
谢谢
附言将此称为“答案”会感到内疚吗?
关于Android BitmapFactory.decodeFile 间歇性地返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19515373/
通过使用方法 BitmapFactory.decodeStream(Resources res,int id) 和 BitmapFactory.decodeFile(String pathName)
我的应用程序从 SD 卡解码大量位图,因此我想重用现有位图以减少 GC 工作。我看到来自 Android Training 的示例和 this video它非常适合 BitmapFactory.dec
哪种设置 ImageView 图像的方法更好(使用更少的堆空间)? imageView.setImageDrawable(Drawable.createFromPath(path)); 或
我在向 gridview 添加可变背景时遇到 OutOfMemoryError...在 final Bitmap shelfBackground = BitmapFactory.decodeResou
url="http://www.nasa.gov/sites/default/files/styles/946xvariable_height/public/ladee_spin_2_in_motio
我打算编写一个小画廊应用程序。所以我有一个带有图像的 gridview,显示的图像被存储在本地设备上。我得到的是一个类 ImageLoader,它在后台线程 (AsyncTask) 中加载特定路径中的
在我的应用程序中,我有一个文件: private File TEMP_PHOTO_FILE = new File(Environment.getExternalStorageDirectory(),
您好,我正在从名为 image.png 的 png 图像创建位图。图像的尺寸为 75(宽)x 92(高)。当我运行这段代码时: Bitmap bitmap = BitmapFactory.decode
在我的 android 应用程序中,我上传和下载 JPEG 图像。对于某些图像,BitmapFactory 对下载的图像进行下采样,我不明白为什么以及如何阻止它这样做。我在上传和下载图像时记录位图对象
我有同一张图片的两份副本。其中一个在应用程序的资源文件夹(默认可绘制对象)中,另一个在外部存储中。 我用以下代码得到了位图: // Get from storage BitmapFactory.d
嘿,我不确定为什么每次我在图库中选择图片时都会出现这个问题? 代码如下: if (v == uploadImageButton) { // below
今天我的应用程序崩溃了,出现内存不足错误。 java.lang.OutOfMemoryError in android.graphics.BitmapFactory.nativeDecodeAsset
我正在尝试从Camera.PictureCallback onPictureTaken获取Jpeg,但是当我这样做时 bitmapImage = BitmapFactory.decodeByteArr
在研究 Android 的 BitmapFactory.Options 类时,我注意到它的字段是公开可以访问和修改的。 这与一般封装规则相反,该规则规定字段应声明为 private,并且应通过 pub
这段代码给出了运行时异常,我无法捕获它。 BitmapFactory.decodeByteArray 不会返回 null 或类似的内容。 Bitmap bitmap = BitmapFactory.d
我有一个包含两列的 ArrayList,并显示下面带有文本的图像。我正在使用高质量图像,并且需要在 GridView 中以良好的质量显示这些图像,为此我使用 BitmapFactory.Options
我应该从互联网获取图像并将其显示在我的 Activity 中。为此,我使用 asynctask 类。我忘记在我的 list 文件中提及互联网权限,并且应用程序成功运行,没有给出任何异常,并且能够获取模
如何从字节数组构造原始大小的位图? byte[] imageAsBytes = Base64.decode(b64.getBytes(), Base64.DEFAULT); Bitma
我在这里从 Cursor 获取值: if (mProfileCursor.moveToFirst()) { byte[] blob = mProfileCursor.getBl
我正在尝试使用这个: BitmapFactory.decodeFile("logo.jpg") 与我的 apk 相比,我似乎没有将文件:logo.jpg 放在正确的位置。它应该去哪里? 附言我得到的错
我是一名优秀的程序员,十分优秀!