美文网首页
Android高级 Glide分析

Android高级 Glide分析

作者: LiuJP | 来源:发表于2020-04-05 10:38 被阅读0次

    image.png
    image.png image.png
    image.png

    知识点1 把请求Builder加入到队列中,开启一个任务处理队列,用Handler处理结果

    package com.example.glidelibrary.task;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Handler;
    import android.os.Looper;
    
    import com.example.glidelibrary.RequestBuilder;
    import com.example.glidelibrary.exception.GlideException;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.concurrent.LinkedBlockingQueue;
    
    
    /**
     * 加载任务
     */
    
    public class DispatcherTask extends Thread {
        private Handler handler;
    
        private LinkedBlockingQueue<RequestBuilder> blockingQueue;
    
    
        public DispatcherTask(LinkedBlockingQueue<RequestBuilder> blockingQueue) {
            this.blockingQueue = blockingQueue;
            handler = new Handler(Looper.getMainLooper());
        }
    
        @Override
        public void run() {
            super.run();
    
            //只要线程没有中断,一直轮训
            while (!isInterrupted()) {
                try {
                    //从队列中获取请求对象
                    RequestBuilder requestBuilder = blockingQueue.take();
                    //设置占位符
                    placeHolder(requestBuilder);
                    //从网路加载图片
                    Bitmap bitmap = loadFromNet(requestBuilder);
                    //显示到控件
                    showBitmap(requestBuilder, bitmap);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void showBitmap(final RequestBuilder requestBuilder, final Bitmap bitmap) {
            if (bitmap != null
                    && requestBuilder.getImageView().get() != null
                    && requestBuilder.getImageView().get().getTag() == requestBuilder.getMd5FileName()) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        requestBuilder.getImageView().get().setImageBitmap(bitmap);
                        if (requestBuilder.getRequestListener() != null) {
                            requestBuilder.getRequestListener().onResourceReady(bitmap);
                        }
    
                    }
                });
            }
        }
    
        private Bitmap loadFromNet(RequestBuilder requestBuilder) {
            InputStream is = null;
            Bitmap bitmap = null;
            try {
                URL url = new URL(requestBuilder.getUrl());
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                is = getInpuStream(connection);
                bitmap = BitmapFactory.decodeStream(is);
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
                requestBuilder.getRequestListener().onLoadFailed(e);
            } finally {
                if (null != is) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return bitmap;
        }
    
        public InputStream getInpuStream(HttpURLConnection urlConnection) throws IOException {
            int code = urlConnection.getResponseCode();
            if (code == 302) {
                String location = urlConnection.getHeaderField("Location");
                return getInpuStream((HttpURLConnection) new URL(location).openConnection());
            } else if (urlConnection.getResponseCode() == 200) {
                return urlConnection.getInputStream();
            }
            return null;
        }
    
        private void placeHolder(final RequestBuilder requestBuilder) {
            if (requestBuilder.getPlaceHolderId() > 0 && requestBuilder.getImageView() != null) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        requestBuilder.getImageView().get().setImageResource(requestBuilder.getPlaceHolderId());
                    }
                });
            }
        }
    }
    
    

    三级缓存

    • 首次从网络获取,并缓存下来
    • 从对象获取
    • 对象中没有从内存中获取
    • 内存中没有从磁盘上获取
    • 磁盘没有重新从网路获取

    相关依赖库
    compile 'com.jakewharton:disklrucache:2.0.2'
    相关代码

    package com.gameassist.plugin.mod.utils;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Environment;
    import android.util.Log;
    import android.util.LruCache;
    
    import com.jakewharton.disklrucache.DiskLruCache;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    import static android.os.Environment.isExternalStorageRemovable;
    
    /**
     * Created by ljp on 2018/8/16.
     */
    
    public class LruCacheUtils {
    
        private static final String TAG = "ggplugin";
        private static final int IO_BUFFER_SIZE = 4096;
        @SuppressLint("StaticFieldLeak")
        private volatile static LruCacheUtils lruCacheUtil;
        private Context context;
    
        private static final int MAX_SIZE = 10 * 1024 * 1024;//10MB
        private DiskLruCache diskLruCache;
        // 获取可用内存的最大值,使用内存超出这个值将抛出 OutOfMemory 异常。LruCache 通过构造函数传入缓存值,以 KB 为单位。
        private final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // 把最大可用内存的 1/8 作为缓存空间
        private final int cacheSize = maxMemory / 8;
    
        public static synchronized LruCacheUtils getInstance() {
            if (null == lruCacheUtil) {
                synchronized (ClientUtils.class) {
                    if (lruCacheUtil == null) {
                        lruCacheUtil = new LruCacheUtils();
                    }
                }
            }
            return lruCacheUtil;
        }
    
    
        private LruCache<String, Bitmap> mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getByteCount() / 1024;
            }
        };
    
    
        public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
            if (getBitmapFromMemCache(key) == null) {
                mMemoryCache.put(key, bitmap);
            }
        }
    
        public Bitmap getBitmapFromMemCache(String key) {
            return mMemoryCache.get(key == null ? "" : key);
        }
    
    
        public static File getDiskCacheDir(Context context, String uniqueName) {
            final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !isExternalStorageRemovable()
                    ? context.getExternalCacheDir().getPath() : context.getCacheDir().getPath();
            return new File(cachePath + File.separator + uniqueName);
        }
    
        public static File getDiskFilesDir(Context context, String uniqueName) {
            final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !isExternalStorageRemovable()
                    ? context.getExternalFilesDir(null).getPath() : context.getFilesDir().getPath();
            return new File(cachePath + File.separator + uniqueName);
        }
    
    
        public void initDiskLruCache(Context context) {
            this.context = context;
            if (diskLruCache == null || diskLruCache.isClosed()) {
                try {
                    File cacheDir = getDiskFilesDir(context, "CacheDir");
                    if (!cacheDir.exists()) {
                        cacheDir.mkdirs();
                    }
                    //初始化DiskLruCache
                    diskLruCache = DiskLruCache.open(cacheDir, 1, 1, MAX_SIZE);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    
        /**
         * A hashing method that changes a string (like a URL) into a hash suitable for using as a
         * disk filename.
         */
        public static String hashKeyForDisk(String key) {
            String cacheKey;
            try {
                final MessageDigest mDigest = MessageDigest.getInstance("MD5");
                mDigest.update(key.getBytes());
                cacheKey = bytesToHexString(mDigest.digest());
            } catch (NoSuchAlgorithmException e) {
                cacheKey = String.valueOf(key.hashCode());
            }
            return cacheKey;
        }
    
        private static String bytesToHexString(byte[] bytes) {
            // http://stackoverflow.com/questions/332079
            StringBuilder sb = new StringBuilder();
            for (byte aByte : bytes) {
                String hex = Integer.toHexString(0xFF & aByte);
                if (hex.length() == 1) {
                    sb.append('0');
                }
                sb.append(hex);
            }
            return sb.toString();
        }
    
    
        boolean lruHttpBitmap(String url) {
            try {
                String key = hashKeyForDisk(url);
                //得到DiskLruCache.Editor
                DiskLruCache.Editor editor = diskLruCache.edit(key);
                if (editor != null) {
                    OutputStream outputStream = editor.newOutputStream(0);
                    if (downloadUrlToStream(url, outputStream)) {
    //                if (HttpUtils.getInstance(context).networkHttpRequest(url, outputStream)) {
    //                    publishProgress("");
                        //写入缓存
                        editor.commit();
                    } else {
                        //写入失败
                        editor.abort();
                    }
    
                }
                diskLruCache.flush();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
    
        public void putDiskValue(String url, InputStream inputStream) {
            try {
                String key = hashKeyForDisk(url);
                //得到DiskLruCache.Editor
                DiskLruCache.Editor editor = diskLruCache.edit(key);
                if (editor != null) {
                    OutputStream outputStream = editor.newOutputStream(0);
                    byte[] buffer = new byte[1024];//out写的时候,每次写1024个字节,如果in有2048个字节数,则读2048/1024=2次
                    int len;
                    while ((len = inputStream.read(buffer)) > 0) {
                        outputStream.write(buffer, 0, len);
                    }
                    editor.commit();
                    outputStream.close();
                }
                inputStream.close();
                diskLruCache.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
    
        public Bitmap getDiskValue(String url) {
            if (diskLruCache != null) {
                try {
                    DiskLruCache.Snapshot snapshot = diskLruCache.get(hashKeyForDisk(url));
                    if (snapshot != null) {
                        return BitmapFactory.decodeStream(snapshot.getInputStream(0));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
    
        /**
         * Download a bitmap from a URL and write the content to an output stream.
         *
         * @param urlString The URL to fetch
         * @return true if successful, false otherwise
         */
        private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
            HttpURLConnection urlConnection = null;
            BufferedOutputStream out = null;
            BufferedInputStream in = null;
    
            try {
                final URL url = new URL(urlString);
                urlConnection = (HttpURLConnection) url.openConnection();
                if (urlConnection != null) {
    //                InputStream inputStream = urlConnection.getInputStream();
                    InputStream inputStream = getInpuStream(urlConnection);
                    if (inputStream != null) {
                        in = new BufferedInputStream(inputStream);
                        out = new BufferedOutputStream(outputStream);
                        int b;
                        while ((b = in.read()) != -1) {
                            out.write(b);
                        }
                        return true;
                    }
                }
            } catch (Exception e) {
                Log.e(TAG, "Error in downloadBitmap - " + e);
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
                try {
                    if (out != null) {
                        out.close();
                    }
                    if (in != null) {
                        in.close();
                    }
                } catch (final IOException ignored) {
                }
            }
            return false;
        }
    
    
        public InputStream getInpuStream(HttpURLConnection urlConnection) {
            try {
                int code = urlConnection.getResponseCode();
                LogUtils.e("code" + code);
                if (code == 302) {
                    String location = urlConnection.getHeaderField("Location");
                    return getInpuStream((HttpURLConnection) new URL(location).openConnection());
                } else if (urlConnection.getResponseCode() == 200) {
                    return urlConnection.getInputStream();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Android高级 Glide分析

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