我有一个列表视图,显示从sd加载的图像(先前用相机拍摄的jpg)。我使用imageView.setImageBitmap()
是因为图像太大,无法显示在列表中,并且消耗太多(native) memory,所以我使用inSampleSize
加载子采样版本。
我的问题是在显示新行之前滚动会延迟。根据设备的不同,延迟或多或少。一旦你到达列表的末尾,滚动就变成了流体。
最初,我在listadapter getview()中执行了位图解码:
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = 2; //Subsample the original image
bitmapOptions.inPurgeable = true; //The system can free the ¿native? memory allocated by the bitmap if needed
bitmapOptions.inInputShareable = true; //Works in conjuction with inPurgeable
bitmap = BitmapFactory.decodeFile(path, bitmapOptions);
imageView.setImageBitmap(bitmap);
然后我尝试在ui线程外执行解码。我执行了一个
AsyncTask
来解码所有的位图并将其缓存在内存中。所以在getview()中我只做了imageView.setImageBitmap()
。但我在滚动时也看到了同样的延迟。使用ddms中的方法剖析工具,我发现方法Canvas.native_drawBitmap()
导致了延迟,所以问题不是位图解码,而是imageview绘图。有什么解决办法吗??为什么第一次显示一行后,显示该行时不再有延迟?可能有一个ImageView显示缓存。
最佳答案
当您滚动列表时,它会在主线程中动态加载。此时,您正在尝试执行setImageBitmap(),而这又在主线程中尝试执行。所以整个任务都慢下来了。
所以解决方案是runonuithread(runnable)或处理程序中的setImageBitmap()。我面对这个问题。这就是解决办法。
编辑:
这样做,
Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
// do setImageBitmap(bitmap)
}
};
new Thread() {
@Override
public void run() {
//get your bitmap
Message message = handler.obtainMessage(0, bitmap);
handler.sendMessage(message);
}
}.start();