【发布时间】:2016-11-11 13:05:29
【问题描述】:
你好,我正在将大量小图像(例如:180x180 10.21kb)从 LOCAL 数据库加载到选项卡布局(嵌套片段)中的视图分页器中的片段中的许多不同的回收器视图中。例如 每个选项卡都有一个新片段使用带有这些小卡片和图像的回收站视图,一切正常,但最终这一切似乎对系统来说有点多,我的应用程序因内存不足错误而被强制关闭,错误指向我的适配器 onBindViewHolder,看起来像这样
@Override
public void onBindViewHolder(MyViewHolder holder, int position){
addNewCard cardmaker = cardMakerListDB.get(position);
holder.cardText.setText(cardmaker.getCardName());
holder.speechText.setText(cardmaker.getCardSpeech());
Drawable drawable = new
BitmapDrawable(Utility.getPhoto(cardmaker.getCardIcon()));
holder.cardImage.setImageDrawable(drawable);
}
特别是它指向这一行
BitmapDrawable(Utility.getPhoto(cardmaker.getCardIcon()));
这是从数据库中获取字节数组并将其转换为位图这是我的实用程序类中的方法
public static Bitmap getPhoto(byte[] image) {
return BitmapFactory.decodeByteArray(image, 0, image.length);
}
任何人都可以看到我看不到的东西,或者我可以做些什么来避免这种情况,我对这一切都很陌生,或者有不同的解决方法欢迎任何建议
编辑
Thought id 试着聪明点,从异步任务中加载所有图像,我实际上不知道这是否能解决我的问题,但我收到此错误
07-10 14:18:28.594 18486-18832/ss.sealstudios.com.socialstories D/skia: --- SkImageDecoder::Factory 返回 null
我明白我只是不知道我需要传递什么方法来修复它这是我尝试过的
我的整个视图持有者试图实现异步任务
public class CardAdapterDB extends
RecyclerView.Adapter<CardAdapterDB.MyViewHolder> {
private List<addNewCard> cardMakerListDB;
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView cardText, speechText;
public ImageView cardImage;
public ProgressBar progress;
public MyViewHolder(View view){
super(view);
cardText = (TextView) view.findViewById(R.id.cardText);
speechText = (TextView) view.findViewById(R.id.speechText);
cardImage = (ImageView) view.findViewById(R.id.cardimage);
progress = (ProgressBar) view.findViewById(R.id.progressBarFetch);
}
}
public CardAdapterDB(List<addNewCard> cardMakerListDB){
this.cardMakerListDB = cardMakerListDB;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position){
addNewCard cardmaker = cardMakerListDB.get(position);
holder.cardText.setText(cardmaker.getCardName());
holder.speechText.setText(cardmaker.getCardSpeech());
holder.progress.setVisibility(View.VISIBLE);
startNewAsyncTask(cardmaker.getCardIcon(),holder.progress,holder);
}
private class MyAsyncTask extends AsyncTask<Bitmap, Void, Bitmap> {
private byte[] data;
private ProgressBar progress;
private MyViewHolder holder;
public MyAsyncTask(byte[] data,ProgressBar progress,MyViewHolder holder)
{
this.data = data;
this.progress = progress;
this.holder = holder;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progress.setVisibility(View.VISIBLE);
progress.setIndeterminate(true);
}
@Override
protected Bitmap doInBackground(Bitmap... data) {
return BitmapFactory.decodeByteArray(this.data, 0, data.length);
}
@Override
protected void onPostExecute(Bitmap response) {
super.onPostExecute(response);
{
Drawable drawable = new BitmapDrawable(response);
holder.cardImage.setImageDrawable(drawable);
// progress.setVisibility(View.GONE);
}
}
}
public void startNewAsyncTask(byte[] image,ProgressBar progress,MyViewHolder
holder) {
MyAsyncTask asyncTask = new MyAsyncTask(image,progress,holder);
asyncTask.execute();
}
@Override
public int getItemCount(){
return cardMakerListDB.size();
}
}
【问题讨论】:
-
你能提供更多关于本地数据库的信息吗?您是否将图像作为 blob 存储在 sqlite 中,然后一次查询多个图像并将它们全部保存在内存中?
-
是的,是的碎片,它可以正常工作,直到出现内存不足错误
-
我想这就是你的答案 - 当你查询一组数据时,你会在内存中保存多个图像,即使它们不会同时在视口中可见(因此不要'不需要在内存中)。考虑将 imgs 保存到磁盘,并将文件路径存储在 db 中 - 然后您可以在需要时使用图像加载器来加载位图。
标签: android android-fragments bitmap bytearray android-adapter