Picaso 图片网络框架的实现

#1. 图片缓存策略





#2. Picaso 图片网络框架的实现 

     Picasso.with(mContext)
            .load(url)
            .into(holder.ivIcon);
强大功能? 时间\资源消耗 处理优化的好?

#3. Davinci

     Davinci.with(mContext)
            .load(url)
            .placeHolder(R.drawable.acq)
            .error(R.drawable.a4h)
            .into(holder.ivIcon);

### 1. Davinci.with(mContext)

    /**
     * 获取该类的实例
     * @param context
     * @return
     */
    public static Davinci with(Context context) {
        mContext = context;
        mCacheMap = new LruCache<>(10*1024*1024);

        //构建一个线程池,里面含有5个线程
        mExecutorService = Executors.newFixedThreadPool(5);

        return singleton;
    }



### 2. load(url)


    /**
     * 也是返回一个实例 RequestCreator
     * @param path
     * @return
     */
    public RequestCreator load(String path) {
        
        return new RequestCreator(path);
    }

    public RequestCreator(String path) {
        this.path = path;
    }

### 3. placeHolder(R.drawable.acq)


         
    public RequestCreator placeHolder(int resId) {
        this.placeHolderResId = resId;
        return this;
    }


       

### 4. error(R.drawable.a4h)


         
    public RequestCreator error(int resId) {
         this.errorResId = resId;
         return this;
    }

### 5.  into(holder.ivIcon);



    public void into(ImageView imageView) {
            this.imageView = imageView;

            //还没有得到图片前先显示默认图片
            imageView.setImageResource(placeHolderResId);

            Bitmap bitmap = getBitmapFromCache();

            Log.d(TAG, "into: 将要请求图片");
            //1.内存中有图片
            if (bitmap != null) {
                Log.d(TAG, "into: 内存中有图片,直接显示");
                imageView.setImageBitmap(bitmap);
                return;
            }

            Log.d(TAG, "into: 内存没有,去磁盘中查找");
            //2.内存中没有,磁盘中有图片
            bitmap = getBitmapFromFile();
            if (bitmap != null) {
                //把图片存在内存
                Log.d(TAG, "into: 磁盘中有图片,直接显示,并且存储到内存");

                mCacheMap.put(path, bitmap);
                imageView.setImageBitmap(bitmap);
                return;
            }

            Log.d(TAG, "into: 磁盘没有图片,去网络获取");
            //3.内存\磁盘都没有图片 ,则从网络下载
            getBitmapFromNet();
        }


*1. 去内存中查找
                 所谓的内存其实就是一些容器集合 (map , List , set , 数组... )

        /**
         * 去内存中获取图片
         * @return bitmap
         */
        private Bitmap getBitmapFromCache() {
            // http://localhost:8080/aaa/bb/cc.jpg
            //这个key其实可以使用url,
            return mCacheMap.get(path);
        }

*2. 去磁盘中查找
    
      private Bitmap getBitmapFromFile() {

            //有可能得到的这个缓存路径是null , 因为也许没有这张图片
            String filePath = getCacheFilePath();
            Bitmap bitmap   = null;
            if (!TextUtils.isEmpty(filePath)) {
                bitmap = BitmapFactory.decodeFile(filePath);
            }
            return bitmap;
        }
*3. 去网络获取

        private void getBitmapFromNet() {
            
            mExecutorService.submit(new LoadImageTask());
        }

    

       class LoadImageTask implements Runnable{
            @Override
            public void run() {

                try {
                    URL               url  = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(1200);
                    conn.setRequestMethod("GET");
                    if (conn.getResponseCode() == 200) {

                        //转化输入流成bitmap
                        InputStream  is     = conn.getInputStream();
                        final Bitmap bitmap = BitmapFactory.decodeStream(is);

                        //1.存到磁盘 把位图存成一张图片
                        FileOutputStream fos = new FileOutputStream(getCacheFilePath());
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);

                        Log.d(TAG, "into: 获取网络图片成功, 存到内存与磁盘,直接显示");

                        //2.存到内存
                        mCacheMap.put(path, bitmap);

                        //3.显示图片
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                imageView.setImageBitmap(bitmap);
                            }
                        }, 1200);

                    } else {
                        showErrorPic();
                    }
                } catch (Exception e) {
                    //请求图片失败
                    e.printStackTrace();

                    showErrorPic();
                }
            }
        }


##优化:  


        * 1. 线程池
        
        * 2. 内存的缓存  2.3前    SoftReference<Bitmap>
                                   4.0后 一视同仁了,都一样


                        存 :
                           new SoftReference<Bitmap>(bitmap)
            
                        取 : 
                        
                            SoftReference<Bitmap> reference = mCacheMap.get(path);
                            Bitmap bitmap = null;
                            if (reference != null){
                                bitmap = reference.get();
                            }


        * 3. 不用bitmap,  用LruCache<K,V>
                        packageManager.freeStoreAndNotify(Integer.Max_VALUE)

        * 4. diskLruChe, 限定磁盘图片存储空间的大小
                (网上有, 官方没给出来)


#4. JAVA的引用类型 Reference


强引用

> 一般我们直接new出来的对象都属于强引用. 即使内存不足,宁愿抛出内存溢出异常,也不回收这个对象的内存

软引用

> SoftReference 内存不足,就回收该对象

        

弱引用

> WeakReference   GC 出来,就回收对象

虚引用

> PhantomReference  用过该对象,就没了。 释放内存。



#5. 问题: 处理listView的时候,出现图片错乱


解决方案
Map<imageView, url>
    map.put(iv1, 01的路径)
     iv1,    01.jpg
     iv2,    02.jpg
        ...
     iv5,    05.jpg

    得到图片的时候  
    run(){
        String oldUrl = map.get(iv);

        if(oldUrl.equal(url)){
            赋值    
        }
    }



##在子线程加载图片 AsyncDrawable处理并发问题

官方文档: 
Develop-
->Training
-->Building Apps with Graphics&Animation
-->Processing Bitmaps Off the UI Thread
-->Handle ConCurrent

    static class AsyncDrawable extends BitmapDrawable {
        private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

        public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
            super(res, bitmap);
            bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
           }

        public BitmapWorkerTask getBitmapWorkerTask() {
            return bitmapWorkerTaskReference.get();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值