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

时间:2015-06-25 15:50:28

标签: android bitmap android-asynctask adapter android-recyclerview

我实际上在Android应用中工作,需要从网上下载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 Thread:

 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);
}

2 个答案:

答案 0 :(得分:1)

请勿使用template<typename S, typename T, typename tuple_element<0,decltype(T::children)>::type > S& operator<<(S& s, const T& t) 将任何类型的数据加载到AsyncTasksRecyclerView

查看Picasso并使用此结构

ListView

从磁盘加载。

答案 1 :(得分:0)

为什么不使用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中启动异步任务。

编辑: 您可以通过以下方式获取该项目 final int position = holder.getAdapterPosition();