android recycleler视图适配器,viewpage,数据库,位图和内存不足错误

时间:2016-07-08 21:16:49

标签: android android-fragments bitmap bytearray android-adapter

你好我从LOCAL数据库加载大量小图片(例如:180x180 10.21kb)到标签布局(嵌套片段)中的浏览器中的片段中的许多不同的回收者视图,例如like this每个标签都有一个新的片段与回收者视图与这些小卡片和图像一切正常但最终它似乎得到了一点系统和我的应用程序强制关闭与内存不足错误错误指向我的适配器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);
}

任何人都可以看到我无法看到的东西,或者我可以做的是为了避免这种情况,我对这一切都很新,或者是否有任何不同的解决方法欢迎任何建议

修改

思考id尝试并且聪明并且从异步任务加载所有图像,我实际上不知道这是否会解决我的问题但是我得到这个错误

07-10 14:18:28.594 18486-18832 / ss.sealstudios.com.socialstories D / skia:--- SkImageDecoder :: Factory返回null

我理解它我只是不知道我需要通过什么方法来修复它继承人我尝试了什么

我的整个视图持有者试图实施ASYNC任务

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

2 个答案:

答案 0 :(得分:2)

显然,大量图片会导致您的应用与OutOfMemoryError一起崩溃,不幸的是,如果您的应用出现此错误,您将无法执行任何操作,它将被迫关闭。

所以,你所能做的就是避免OutOfMemoryError,这可以通过很多方式来完成:

1。为您的应用分配largeHeap

您可以将android:largeHeap="true"添加到 manifest.xml 文件中的<application>标记。

2。会覆盖您活动的onLowMemory方法,如果系统感觉内存在某些时候非常低,您可以采取行动:

@Override
    public void onLowMemory() {
        // you can here remove the Bitmaps or stopping the process of generating images or do whatever you want to survive being trapped into 'OutOfMemoryError'.
    };

3。您可以使用任何图片库来更改检索到的图片的设置,例如降低其分辨率缩小其尺寸,甚至减少其颜色集,以这种方式使用的最常见的将是Universal-Image-LoaderPicasso,例如 Universal- Image-Loader 您可以在下载和显示Bitmap的任何过程中使用它:

enter image description here

在你的情况下,你已经加载了Bitmap,你想要的只是使用一个图像库来编辑它的选项(这里我们将使用 UniversalImageLoader ),在这种情况下你可以保存图像如上所述是this answer,之后用你给它的选项从内存中加载它:

// Saving image to disk
String filename = "some_name.jpg";
File sd = Environment.getExternalStorageDirectory();
File dest = new File(sd, filename);

Bitmap bitmap = (Bitmap)data.getExtras().get("data");
try {
     FileOutputStream out = new FileOutputStream(dest);
     bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
     out.flush();
     out.close();
} catch (Exception e) {
     e.printStackTrace();
}

// this is an example of the used options
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
options.inJustDecodeBounds = true;
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;

// create ImageLoader instance
ImageLoader loader = ImageLoader.getInstance();
loader.loadImageSync(dest.getAbsolutePath(), options);

答案 1 :(得分:1)

尝试使用Picasso依赖:compile 'com.squareup.picasso:picasso:2.5.2

Picasso
  .with(context)
  .load(your_image)
  .fit()
  // call .centerInside() or .centerCrop() to avoid a stretched image
  .into(your_imageview);