Android中无法从SD卡高效加载大型位图

Android中无法从SD卡高效加载大型位图,android,bitmap,Android,Bitmap,通过以下步骤,我编写了以下代码来显示SD卡中的大型图像位图 try { InputStream lStreamToImage = context.getContentResolver().openInputStream(Uri.parse(imagePath)); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFac

通过以下步骤,我编写了以下代码来显示SD卡中的大型图像位图

try {
   InputStream lStreamToImage = context.getContentResolver().openInputStream(Uri.parse(imagePath));
   BitmapFactory.Options options = new BitmapFactory.Options();
   options.inJustDecodeBounds = true;
   BitmapFactory.decodeStream(lStreamToImage, null, options);
   options.inSampleSize = 8; //Decrease the size of decoded image
   options.inPreferredConfig = Bitmap.Config.ARGB_4444;
   options.inJustDecodeBounds = false;
   bitmap = BitmapFactory.decodeStream(lStreamToImage, null, options);
} catch(Exception e){}
image.setImageBitmap(bitmap);
但是它没有返回位图(我的意思是它返回null)。在logcat中,重复显示以下消息

08-02 17:21:04.389: D/skia(19359): --- SkImageDecoder::Factory returned null
如果我将注释选项.inJustDecodeBounds行并重新运行它,它工作正常,但运行缓慢。我上面提供的开发者指南链接说,使用inJustDecodeBounds高效加载位图


请告诉我哪里做错了

inJustDecodeBounds
不加载位图。这就是重点。它在不加载实际位图的情况下加载位图的尺寸,因此您可以在实际加载位图之前对位图进行任何预处理或检查。这是很有帮助的,比如说,你有内存问题,你需要检查加载位图是否会使你的程序崩溃

位图加载缓慢的原因可能是因为它可能非常大,而SD卡非常慢

编辑

如果设置为true,解码器将返回null(无位图),但输出。。。字段仍将被设置,允许调用者查询位图,而不必为其像素分配内存

编辑2:

用Google提供的示例查看您的代码,看起来您做的事情相对来说是相同的。返回null的原因可能是您的
InputStream
在第一次解码时已被修改,因此没有从位图内存地址的开头开始(它们使用资源ID而不是
InputStream

根据你在这里提供的代码,我得出了以下结论。无论第一次解码给你什么,你总是将样本大小设置为8。谷歌第一次解码的原因是要找出位图的实际大小与他们想要的大小。他们确定位图是ZxZ维,他们想要YxY维ons,因此他们计算第二次解码时应使用的
采样大小
。您没有这样做。您只是检索位图的尺寸,而不使用它们。然后,您将样本大小设置为硬编码
8
,将其交换为硬编码
ARGB_4444
位图,然后解码完整的位图p进入内存。换句话说,这三行没有被使用:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(lStreamToImage, null, options);
设置
inJustDecodeBounds
只会给出位图的尺寸,而不会将位图放入内存。这并不能提高效率。如果位图太大,您可以在较小的内存空间中加载位图,因为您可以预先决定位图的大小,而无需对整个内容进行解码)


解码位图速度慢的原因可能只是CPU的问题。根据位图的大小,您正在从SD卡的
InputStream
加载位图,这本身就是一个缓慢的操作。

DeeV亲爱的DeeV,文档中说,如果设置为true,它将返回null,但会预处理它。但是如果你想得到预处理过的位图,那么把它设置为false并重新设置它。我在上面所做的。请看上面给出的文档链接,它也做了同样的事情。我认为他们说“处理它”的时候弄错了。它“处理”图像的意思是,它将给你图像的大小,而不完全解码它。旁注,我似乎还记得一个月前的一个问题,有人试图重新使用同一个选项对象,但它不断地砸到他身上。最后,他不得不创建一个新的。这是否奏效?我正在再次查看您的代码,并试图找出哪里出了问题。除了重新使用BitmapFactory.Options对象(由于某些原因会导致问题),我在提供的段中看不到任何内容。请为此提供解决方案。实际上,它总是返回null。我需要在上面的代码中更改什么。请参阅我的编辑。我认为它返回null是因为正在修改
InputStream