美文网首页
Picasso加载图片OOM的一些小经验

Picasso加载图片OOM的一些小经验

作者: ytuio21 | 来源:发表于2016-11-18 15:42 被阅读318次

    关于RecyclerView的一点小事

    最近用RecyclerView做了一个图片列表,遇到了好几个OOM的坑,特别记录一下,首先是RecyclerView的使用上,原谅我是从listview转过来的一时没适应过来,listview的BaseAdapter里面有getPostion和getItem的方法重写,我们随便就能获得postion或者对应的item,到了RecyclerView我没找到getPostion方法,RecyclerView.ViewHolder里面的getAdapterPosition方法不能在初始化时获取postion,所以一时抽风重写了getItemViewType()方法返回postion,然后事情大条了,RecyclerView里是根据ItemViewType判断类型是否相同然后回收重用,所以一旦getItemViewType()方法返回postion,就表示着你的每个item不会回收复用,会一直填充新的itemView然后就oom了,虽然我知道大多数程序员没我这么傻,可是还是写给某些偶尔会脑抽的人参考一下。
    我现在主要使用的还是getAdapterPosition()方法,只要不是需要在初始化时获取相对应的postion都可以用(要在初始化里面获取postion的建议放到onBindViewHolder方法里面,自带postion参数),具体的例子可以看看下面的给view加上点击事件的代码:

        public ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
        View view = mInflater.inflate(R.layout.recy_item_second_case,parent,false);
    
          final ViewHolder holder = new ViewHolder(view);
          holder.itemView.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  int position = holder.getAdapterPosition();
                  Intent intent2 = new Intent(mContext, CaseActivity.class);
                  intent2.putExtra("id",mDatas.get(position).getId()+"");
                  mContext.startActivity(intent2);
            }
          });
    
           return holder;
         }
    

    接下来是Picasso的使用上遇到的问题

    以前一开始用的时候问题还不大,直到最近后台把开始把几M的缩略图传给我,3000多的宽高分辨率几张就把内存爆到100多了,不过这也怪我当初考虑不周,设计图要求图片宽度匹配屏幕,然后高度按比例自适应,图片的分辨率早就超出屏幕宽度了,所以加载这么大的图片是浪费内存资源,我就想着把bitmap缩小,一开始用的下面这个方法,在Picasso.transform(transformation)里面做处理当图片宽度大于屏幕时根据屏幕的width重新createScaledBitmap一个缩放的bitmap。

        Transformation transformation = new Transformation() {
    
            @Override
            public Bitmap transform(Bitmap source) {
                int targetWidth = width;
    
                if (source.getWidth()<=width){
                    return source;
                }
    
                double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
                int targetHeight = (int) (targetWidth * aspectRatio);
                if (targetHeight != 0 && targetWidth != 0) {
                    Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
                    if (result != source) {
                        source.recycle();
                    }
                    return result;
                } else {
                    return source;
                }
    
            }
    
            @Override
            public String key() {
                return "transformation" + " desiredByWidth";
            }
        };
    

    可是程序一跑起来内存占用并不能马上降下来,虽然我调用了source.recycle(),可是内存还是会涨到一个超过100m的峰值后面才下降,我试了用Picasso自身的resize方法的话就不会产生这么高的峰值,所以就想着不生成新的bitmap而是直接把根据屏幕宽度压缩后的宽高传给Picasso.resize(width,height)。

    public static void displayCorpByResize(final ImageView img, String url, final int width){
    
    
        final double[] scaled = {0};
    
        Transformation transformation = new Transformation() {
            @Override
            public Bitmap transform(Bitmap source) {
                scaled[0] = (double) source.getHeight() / (double) source.getWidth();
                return source;
            }
    
            @Override
            public String key() {
                return "transformation" + " desiredByResize";
            }
        };
    
        if (!TextUtils.isEmpty(url)) {
    
            Picasso.with(mContext)
                    .load(url)
                    .config(Bitmap.Config.RGB_565)
                    .transform(transformation)
                    .resize(width, (int) (width*scaled[0]))
                    .placeholder(R.drawable.load_photo_big)
                    .into(img);
    
        }
    
    }
    

    这样虽然是解决了内存暴涨的问题,可是这代码的写法看起来连我都觉得有点别扭,各位大牛如果知道有什么好的写法请务必告诉我,网上都没找到对应的方法,所以才用这种别扭的方法。当然网络上许多朋友说Picasso内存占用大是老问题了,想要内存占用问题少点最好试试看glide和fresco框架,最后再谢谢这位老兄提供的自适应高度的ImageView

    相关文章

      网友评论

          本文标题:Picasso加载图片OOM的一些小经验

          本文链接:https://www.haomeiwen.com/subject/ljtspttx.html