我有一个ListView,显示从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显示缓存。
答案 0 :(得分:3)
当您滚动列表时,它会在主线程中动态加载。那时你正试图做 setImageBitmap(),而这又是在主线程中尝试做的。所以整个任务都放慢了速度。
因此解决方案是 runOnUiThread(可运行)或处理程序中的 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();
答案 1 :(得分:0)
滚动视图时,会调用列表适配器的getView()方法。这意味着,加载到此方法的工作量越多,延迟就越多。