跳过451帧!应用程序可能在其主线程上做了太多工作

时间:2015-09-03 08:15:06

标签: android multithreading android-listview

我知道这里有类似的问题。但我尝试了可能的解决方案,但仍然有错误。

我正在创建一个包含图像和文本视图的列表视图。从数据库中检索图像的路径。现在我想在列表视图的行中加载图像。在我的活动中,我在onCreate中这样做 代码段是

new Thread(new Runnable() {
     @Override
        public void run() {
            if (Looper.myLooper() == null)
                Looper.prepare();
                adapter = new ViewAdapter(getApplicationContext(), cursor);
            }
    }).start();

在Adapter类中我正在做这个

class ViewAdapter extends CursorAdapter {
        @Override
        public void bindView(View view, Context context, Cursor cur) {

            new ImgAdapter_My_list(image,pic).execute();
 ....
           }
}

ImgAdapter_My_list扩展asynctask以降低主线程上的负载

public class ImgAdapter_My_list extends  AsyncTask<Object, Void, Bitmap>       {

    private ImageView imv;
    private String path;

    public ImgAdapter_My_list(ImageView imv,String path) {
        this.imv = imv;
        this.path=path;
    }

    @Override
    protected Bitmap doInBackground(Object... params) {
        Bitmap bitmap = null;
        File file = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath() + path);

        if (file.exists()) {
            bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
        }
        //Bitmap bitmap = ((BitmapDrawable)imv.getDrawable()).getBitmap();

        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap result) {

        if (result != null && imv != null) {
            Log.d("test", "post exe  success");
            imv.setVisibility(View.VISIBLE);
            imv.setImageBitmap(result);
        } else {
            Log.d("test","result=" + String.valueOf(result == null)); //result is null here
            Log.d("test","imv=" + String.valueOf(imv == null));
            Log.d("test","fail");
            imv.setVisibility(View.GONE);
        }
    }
}

毕竟这是我在主线程错误上得到太多工作。请帮忙

1 个答案:

答案 0 :(得分:2)

不应该将ViewAdapter推入自己的线程。实际上,在这种情况下,由于你想对每一行进行一些处理,我会完全放弃使用CursorAdapter。我发现CursorAdapter实际上只在数据库返回的数据是ListView的即时“摘要”形式(即原始文本)时才有用。

相反,我会使用AsyncTask加载数据库中的所有数据并一次处理它,将结果加载到自定义对象中,然后构建一个利用自定义的ArrayAdapter要显示的对象。

自定义类对象:

public class ImageObject {
    private String text;
    private String path;
    private Bitmap image;

    public ImageObject(String text, String path) {
        this.text = text;
        this.path = path;
    }

    //Getters and setters for the class variables.
}

我的工作流程图如下:

  1. AsyncTask连接数据库,运行查询,并筛选 结果将每一行放入ArrayList的{​​{1}}。
  2. 在每一行上,它会执行您上面的ImageObjects代码,并将File放入Bitmap
  3. ImageObject返回AsyncTask
  4. 然后将ArrayList<ImageObject>传递给自定义 ArrayList<ImageObjects>,数据就是最终形式,准备就绪 显示。
  5. 希望这是有道理的,如果您有疑问,请告诉我!