美文网首页
自定义ImageLoader

自定义ImageLoader

作者: itbird01 | 来源:发表于2022-03-15 07:12 被阅读0次

    近期看了一些设计模式相关的书籍,突然有了一个想法,借助所学,去实现一个图片加载框架。

    1.UML设计

    image.png

    从图中可以看到面向对象的几大设计原则
    1)依赖倒置原则:高层模块(ImageLoader)只依赖于接口or抽象类(ImageCache),不依赖具体的实现类(DiskImageCache、MemoryImageCache等具体的实现类)
    2)单一职责原则:加载业务、不同的缓存业务相分离,实现了解耦、分离
    3)开闭原则:修改不同的缓存策略、用户不同的自定义缓存策略,都可以通过继承ImageCache接口类实现具体的缓存类,而且过程中,ImageLoader、ImageCache不再需要改动,只需改动上层调用处(Activity)
    4)里氏代换原则:基类出现的地方,都可以通过子类来替代,在ImageLoader内部只有ImageCache的基类对象存在,在activity中调用时,ImageLoader内部传入具体的实现类(DiskImageCache、Memory...)
    5)接口隔离原则:使接口功能尽可能的少、分离,此处无体现,当然,如果我们有更多复杂的场景和需求,不要把所有功能接口都写在ImageLoader内部,而是根据不同的业务类型去封装不同的业务接口,实现接口隔离
    6)迪米特原则(最小知道原则):一个类对另外一个类的了解,尽可能的少,此处未体现

    2.代码实现

    ImageCache

    package com.itbird.imageloader;
    
    import android.graphics.Bitmap;
    
    /**
     * Created by itbird on 2022/2/28
     */
    public interface ImageCache {
        Bitmap get(String url);
    
        void put(String url, Bitmap bitmap);
    
        void remove(String url);
    }
    
    

    DiskImageCache

    package com.itbird.imageloader;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Environment;
    import android.text.TextUtils;
    import android.util.Log;
    import android.util.LruCache;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    /**
     * Created by itbird on 2022/2/28
     */
    public class DiskImageCache implements ImageCache {
        @Override
        public Bitmap get(String url) {
            return BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + url.substring(url.lastIndexOf("/")));
        }
    
        @Override
        public void put(String url, Bitmap bitmap) {
            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + url.substring(url.lastIndexOf("/")));
            Log.d("itbird", file.getAbsolutePath());
            FileOutputStream outputStream = null;
            try {
                outputStream = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        @Override
        public void remove(String url) {
            if (TextUtils.isEmpty(url)) {
                return;
            }
    
            File file = new File("/sdcard/Pictures/" + url);
            if (file == null || !file.exists()) {
                return;
            }
            file.delete();
        }
    }
    
    

    MemoryImageCache

    package com.itbird.imageloader;
    
    import android.graphics.Bitmap;
    import android.util.LruCache;
    
    /**
     * Created by itbird on 2022/2/28
     */
    public class MemoryImageCache implements ImageCache {
        LruCache<String, Bitmap> bitmapLruCache;
    
        public MemoryImageCache() {
            bitmapLruCache = new LruCache<>(10);
        }
    
        @Override
        public Bitmap get(String url) {
            return bitmapLruCache.get(url);
        }
    
        @Override
        public void put(String url, Bitmap bitmap) {
            bitmapLruCache.put(url, bitmap);
        }
    
        @Override
        public void remove(String url) {
            bitmapLruCache.remove(url);
        }
    }
    
    

    MymageCache

    package com.itbird.imageloader;
    
    import android.graphics.Bitmap;
    
    /**
     * Created by itbird on 2022/2/28
     */
    public class MymageCache implements ImageCache {
        MemoryImageCache memoryImageCache;
        DiskImageCache diskImageCache;
    
        public MymageCache() {
            memoryImageCache = new MemoryImageCache();
            diskImageCache = new DiskImageCache();
        }
    
        @Override
        public Bitmap get(String url) {
            Bitmap bitmap = memoryImageCache.get(url);
            if (bitmap != null) {
                return bitmap;
            }
    
            bitmap = diskImageCache.get(url);
            if (bitmap != null) {
                return bitmap;
            }
            return null;
        }
    
        @Override
        public void put(String url, Bitmap bitmap) {
            memoryImageCache.put(url, bitmap);
            diskImageCache.put(url, bitmap);
        }
    
        @Override
        public void remove(String url) {
            memoryImageCache.remove(url);
            diskImageCache.remove(url);
        }
    }
    
    

    ImageLoader

    package com.itbird.imageloader;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.PixelFormat;
    import android.os.Handler;
    import android.os.Message;
    import android.text.TextUtils;
    import android.util.Log;
    import android.widget.ImageView;
    
    import androidx.annotation.NonNull;
    
    import java.io.BufferedInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.lang.ref.WeakReference;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * Created by itbird on 2022/2/28
     */
    public class ImageLoader {
        private volatile static ImageLoader mInstance;
        private ImageCache mImageCache;
        ExecutorService mExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        private WeakReference<Context> mContext;
        private Handler mHandler;
    
        public static ImageLoader getInstance(Context context) {
            if (mInstance == null) {
                synchronized (ImageLoader.class) {
                    if (mInstance == null) {
                        mInstance = new ImageLoader(context);
                    }
                }
            }
            return mInstance;
        }
    
        private ImageLoader(Context context) {
            mContext = new WeakReference<>(context);
            mHandler = new Handler(context.getMainLooper());
        }
    
        public void setImageLCache(ImageCache imageLCache) {
            mImageCache = imageLCache;
        }
    
    
        public void setImageView(String url, ImageView imageView) {
            if (TextUtils.isEmpty(url) || imageView == null) {
                return;
            }
            Bitmap bitmap = mImageCache.get(url);
            if (bitmap == null) {
                imageView.setTag(url);
                downloadImage(url, imageView);
            } else {
                imageView.setImageBitmap(bitmap);
            }
        }
    
        private void downloadImage(String url, ImageView imageView) {
            mExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    Bitmap bitmap = downloadUrlBitmap(url);
                    if (TextUtils.equals((CharSequence) imageView.getTag(), url)) {
                        Log.e("itbird", "" + bitmap.getByteCount());
                        //cackback主线程
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                imageView.setImageBitmap(bitmap);
                            }
                        });
                    }
                    if (mImageCache != null) {
                        mImageCache.put(url, bitmap);
                    }
                }
            });
        }
    
        private Bitmap downloadUrlBitmap(String urlString) {
            HttpURLConnection urlConnection = null;
            BufferedInputStream in = null;
            Bitmap bitmap = null;
            try {
                final URL url = new URL(urlString);
                urlConnection = (HttpURLConnection) url.openConnection();
                in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
                bitmap = BitmapFactory.decodeStream(in);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
                byte[] bytes = bos.toByteArray();
                bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            } catch (final IOException e) {
                e.printStackTrace();
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (final IOException e) {
                    e.printStackTrace();
                }
            }
            return bitmap;
        }
    }
    

    相关文章

      网友评论

          本文标题:自定义ImageLoader

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