由于ImageView绘图,Android ListView滚动延迟

时间:2012-08-16 09:51:48

标签: android android-listview android-imageview

我有一个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显示缓存。

2 个答案:

答案 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()方法。这意味着,加载到此方法的工作量越多,延迟就越多。