sro*_*mku 21 android garbage-collection bitmap bitmapfactory
我得到了下一个异常:当设置为true 时,问题解码到现有位图inBitmap ;
引起:java.lang.IllegalArgumentException:
在android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:460)解码到现有位图时出现问题
...
有趣的是,在运行时,相同的代码在不同的地方失败:
这是我的代码,它是这个DevBytes:Bitmap Allocation视频中显示的副本.
private BitmapFactory.Options options;
private Bitmap reusedBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView imageView = (ImageView) findViewById(R.id.image_view);
// set the size to option, the images we will load by using this option
options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inMutable = true;
BitmapFactory.decodeResource(getResources(), R.drawable.img1, options);
// we will create empty bitmap by using the option
reusedBitmap = Bitmap.createBitmap(options.outWidth, options.outHeight, Bitmap.Config.ARGB_8888);
// set the option to allocate memory for the bitmap
options.inJustDecodeBounds = false;
options.inSampleSize = 1;
options.inBitmap = reusedBitmap;
// #1
reusedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img1, options);
imageView.setImageBitmap(reusedBitmap);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
options.inBitmap = reusedBitmap;
// #2
reusedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img2, options);
imageView.setImageBitmap(reusedBitmap);
}
});
}
Run Code Online (Sandbox Code Playgroud)
BitmapFactory.decodeResource()时// #1BitmapFactory.decodeResource()处的图像崩溃// #2jpg和png.两者都失败了.canUseForInBitmap按照此处所述使用此方法进行了检查.如何inBitmap正确使用此属性?
如果你遇到这样的问题,或者你发现我做了些蠢事,请评论/回复.任何帮助将不胜感激.如果你知道任何解决方法,它会很棒.
很抱歉没有解释为什么我试图以这种方式重用位图的原因.
原因是GC每次决定释放内存时都会锁定.
inBitmap功能应该帮助我们重用位图而不分配新的内存,这将导致GC清理已经分配的内存.
例如,如果我使用这种常见方法:
Log.i("my_tag", "image 1");
imageView.setImageResource(R.drawable.img1);
Log.i("my_tag", "image 2");
imageView.setImageResource(R.drawable.img2);
Log.i("my_tag", "image 3");
imageView.setImageResource(R.drawable.img3);
Run Code Online (Sandbox Code Playgroud)
然后这将是GC工作:
I/my_tag ( 5886): image 1
D/dalvikvm( 5886): GC_FOR_ALLOC freed 91K, 2% free 9113K/9240K, paused 15ms, total 15ms
I/dalvikvm-heap( 5886): Grow heap (frag case) to 19.914MB for 11520016-byte allocation
D/dalvikvm( 5886): GC_FOR_ALLOC freed <1K, 1% free 20362K/20492K, paused 13ms, total 13ms
I/my_tag ( 5886): image 2
D/dalvikvm( 5886): GC_FOR_ALLOC freed 11252K, 2% free 9111K/9236K, paused 15ms, total 15ms
I/dalvikvm-heap( 5886): Grow heap (frag case) to 19.912MB for 11520016-byte allocation
D/dalvikvm( 5886): GC_FOR_ALLOC freed <1K, 1% free 20361K/20488K, paused 35ms, total 35ms
I/my_tag ( 5886): image 3
D/dalvikvm( 5886): GC_FOR_ALLOC freed 11250K, 2% free 9111K/9236K, paused 15ms, total 15ms
I/dalvikvm-heap( 5886): Grow heap (frag case) to 19.913MB for 11520016-byte allocation
D/dalvikvm( 5886): GC_FOR_ALLOC freed <1K, 1% free 20361K/20488K, paused 32ms, total 32ms
Run Code Online (Sandbox Code Playgroud)
这是超过100ms的锁定主线程!
如果我decodeResource()没有inBitmap选择,也会发生同样的事情.那么问题仍然是开放的,如何使用这个属性?
我用模拟的 Nexus 4 尝试了你的代码。
我有默认的 ic_launcher.png 文件,我将其复制并粘贴到drawable-mdpi 中两次(就像我通常做的那样)。我重命名了这两个新文件以匹配代码中的名称(这样我就可以减少需要进行的更改)。
当我运行该应用程序时,我观察到的情况与您相同。
经过几次不同的尝试后,我决定将新的 png 复制到其他可绘制文件夹 - 所以它们存在于:
我运行该应用程序并且它正在工作!
我不太确定为什么它真的有效,但显然它必须具有正确的屏幕分辨率/密度。