使用 Asynctask 从 internalStorage 加载 recyclerView 中的位图

Load bitmap in recyclerView from internalStorage with Asynctask

我实际上在 Android 应用程序中工作,该应用程序需要从 Web 下载 PNG 并将其显示在 recyclerView 中。下载部分工作正常,与内部存储中的保存相同。问题出在显示上,当我将它加载到我的 onBindViewHolder 的 AsyncTask 中时,这不是流畅的......并且在 AVD 上我有一个异常,比如资源未关闭。所以我将粘贴适配器:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
private static final String TAG = "MyAdapter";
private List<Item> listItem = null;

public MyAdapter(List<Item> listItem) {
    this.listItem = listItem;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Log.d(logTag, "view group " + parent);
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
    return new MyViewHolder(v);
}

@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
    //Log.d(logTag, " bind " + position + " holder " + holder);
    final Item item = listItem.get(position);

    holder.position = position;
    //new LoadBitmap(position, holder).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, item.getId());
}

private class LoadBitmap extends AsyncTask<String, Void, Bitmap> {
    private MyViewHolder holder = null;
    private int position = 0;

    public LoadBitmap(int position, MyViewHolder holder) {
        this.holder = holder;
        this.position = position;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        File file = new File("/data/data/myapp/files", params[0]);
        FileInputStream fis = null;
        Bitmap bitmap = null;
        try {
            fis = new FileInputStream(file);
            bitmap = BitmapFactory.decodeStream(fis);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (bitmap != null && holder.position == position) {
            holder.imageView.setImageBitmap(bitmap);
        }
    }
}


@Override
public int getItemCount() {
    return listItem.size();
}


public class MyViewHolder extends RecyclerView.ViewHolder {
    private ImageView imageView = null;

    int position = 0;

    public MyViewHolder(View itemView) {
        super(itemView);
        imageView = (ImageView) itemView.findViewById(R.id.imageView_item);
    }
}

}

我也尝试 UI 主题 :

 holder.imageView.post(new Runnable() {
        @Override
        public void run() {
            File file = new File("/data/data/myapp/files", item.getId());
            FileInputStream fis = null;
            Bitmap bitmap = null;
            try {
                fis = new FileInputStream(file);
                bitmap = BitmapFactory.decodeStream(fis);
                holder.imageView.setImageBitmap(bitmap);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    });

我希望它足够清楚,对不起我的英语。 谢谢

编辑: 此修复工作完美

@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
    Item item = listItem.get(position);

    holder.position = position;
    File file = new File("/data/data/myApp/files", item.getId());
    Picasso.with(holder.itemView.getContext()).load(file).resize(50,25).centerCrop().into(holder.imageView);
}

永远不要使用 AsyncTasks 将任何类型的数据加载到 RecyclerViewListView

查看 Picasso 并使用此构造

File file = new File(path);
Picasso.with(context).load(file).placeholder(placeholderResId).into(imageView);

从磁盘加载。

为什么不为此使用 Picasso 或库?

就这么简单:

Uri uri = Uri.fromFile(yourFilePath);

Picasso.with(activity).load(uri)
            .resize(100, 100).centerCrop().into(viewHolder.imageView);

或者在onCreateViewHolder方法中加载图片

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Log.d(logTag, "view group " + parent);
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
ImageView imgView = v.findViewById(R.id.yourId);
final int position = holder.getAdapterPosition(); //get your item with position 

new LoadBitmap( ...)
    return new MyViewHolder(v);
}

并且不要忘记使用 bitmap.recycle()

回收您的位图

但永远不要在 onBindViewHolder 中启动异步任务。

编辑: 您可以通过以下方式获得该项目: 最终整数位置 = holder.getAdapterPosition();