美文网首页
简单仿写Glide框架

简单仿写Glide框架

作者: 伊泽瑞额 | 来源:发表于2019-11-08 09:10 被阅读0次
根据下图思路:
image.png
首先封装一个请求体BitmapRequest
package com.amn.amn.amnglide;

import android.content.Context;
import android.widget.ImageView;

import java.lang.ref.SoftReference;
import java.net.URI;

/**
 * 秃瓢请求体的封装
 */
public class BitmapRequest {

    //请求地址
   private String url;

   //上下文
    private Context context;

    //加载图片的控件
    private SoftReference<ImageView> imageView;

    //加载图片时的占位符
    private  int resId;

    //图片标识,1.防止ViewHold 复用图片错位 2.缓存图片时作为唯一的key
    private String urlMD5;

    //回调对象 用来图片请求成功时返回bitmap成功时修改圆角或者其他处理  2.用于顺序排列 图片请求成功后在取请求第二个请求。
    private RequestListenner requestListenner;


    public BitmapRequest(Context context){
        this.context=context;
    }



    public BitmapRequest load(String url){
        this.url=url;
        this.urlMD5=MD5Util.toMD5(url);
        return this;
    }


    public BitmapRequest loading(int resId){
        this.resId=resId;
        return this;
    }

    public BitmapRequest listener(RequestListenner listenner){
        this.requestListenner=listenner;
        return this;
    }

    public void into(ImageView imageView){
        imageView.setTag(this.urlMD5);
        this.imageView=new SoftReference<>(imageView);
        //将请求 添加到框架中
        RequestManager.getInstance().addRequest(this);
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    public ImageView getImageView() {
        return imageView.get();
    }

    public int getResId() {
        return resId;
    }

    public void setResId(int resId) {
        this.resId = resId;
    }

    public String getUrlMD5() {
        return urlMD5;
    }

    public void setUrlMD5(String urlMD5) {
        this.urlMD5 = urlMD5;
    }

    public RequestListenner getRequestListenner() {
        return requestListenner;
    }

    public void setRequestListenner(RequestListenner requestListenner) {
        this.requestListenner = requestListenner;
    }

}
然后将请求体分发到消费柜台取消费也就是BitmapDispatcher 主要是对请求经行处理
package com.amn.amn.amnglide;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.widget.EditText;
import android.widget.ImageView;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * 处理图片请求
 */
public class BitmapDispatcher extends Thread {

    private Handler handler = new Handler(Looper.getMainLooper());

    //定义一个阻塞队列
    private LinkedBlockingDeque<BitmapRequest> requestQueue;

    public BitmapDispatcher(LinkedBlockingDeque<BitmapRequest> requestQueue) {
        this.requestQueue = requestQueue;//不负责队列的创建接受别人传过来。
    }


    @Override
    public void run() {
        super.run();
        while (!isInterrupted()) {//不断的取监听是否有请求
            // !isInterrupted() 线程没被意外终止

            try {
                BitmapRequest request = requestQueue.take();
                //设置占位符
                showLoadingImg(request);
                //加载图片
                Bitmap bitmap = findBitmaprequest(request);
                if(bitmap != null){
                    request.getRequestListenner().onSuccess(bitmap);
                }else {
                    request.getRequestListenner().onFailure();
                }
                //把图片显示到imageView
                showImageview(request, bitmap);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }

    private void showImageview(BitmapRequest request, final Bitmap bitmap) {
        if (bitmap != null && request.getImageView() != null &&
                request.getUrlMD5().equals(request.getImageView().getTag())) {
            final ImageView imageView = request.getImageView();
            handler.post(new Runnable() {
                @Override
                public void run() {
                    imageView.setImageBitmap(bitmap);
                }
            });

        }
    }

    private Bitmap findBitmaprequest(BitmapRequest request) {

        Bitmap bitmap = null;
        bitmap = downloadBimap(request.getUrl());
        return bitmap;
    }

    private Bitmap downloadBimap(String uri) {
        FileOutputStream fos = null;
        InputStream is = null;
        Bitmap bimap = null;

        try {
            URL url = new URL(uri);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            is = conn.getInputStream();
            bimap = BitmapFactory.decodeStream(is);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e) {

            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (Exception e) {

            }
        }
        return bimap;
    }

    private void showLoadingImg(BitmapRequest request) {
        if (request.getResId() > 0 && request.getImageView() != null) {
            final int resId = request.getResId();
            final ImageView imageView = request.getImageView();
            handler.post(new Runnable() {
                @Override
                public void run() {
                    imageView.setImageResource(resId);
                }
            });
        }
    }


}

创建一个管理类主要是线程池,队列的创建
package com.amn.amn.amnglide;

import java.util.concurrent.LinkedBlockingDeque;

public class RequestManager {

    //创建队列,存放bitmap请求
    private LinkedBlockingDeque<BitmapRequest> requestQueue =new LinkedBlockingDeque<>();

    //定义一个线程数组
    private  BitmapDispatcher[] bitmapDispatchers;

    private static RequestManager requestManager=new RequestManager();

    private RequestManager(){
        start();
    }

    private void start() {
        stop();
        startAllDispatcher();
    }

    private void stop() {
        if(bitmapDispatchers != null&& bitmapDispatchers.length>0){
            for (BitmapDispatcher dispatcher:bitmapDispatchers){
                if(!dispatcher.isInterrupted()){
                    dispatcher.isInterrupted();
                }
            }
        }
    }

    private void startAllDispatcher() {
        //获取手机支持的单个应用最大线程数
        int threadCount=Runtime.getRuntime().availableProcessors();
        bitmapDispatchers=new BitmapDispatcher[threadCount];
        for (int i=0;i<threadCount;i++){
            BitmapDispatcher bitmapDispatcher = new BitmapDispatcher(requestQueue);
            bitmapDispatcher.start();
            //需要将所有的dispatcher 存放到数组中,方便统一管理
            bitmapDispatchers[i]=bitmapDispatcher;
        }

    }

    public static  RequestManager getInstance(){
        return requestManager;
    }


    /**
     * 将请求加入队列中
     *
     */
    public void addRequest(BitmapRequest bitmapRequest){
        if(bitmapRequest ==null){
            return;
        }
        if(!requestQueue.contains(bitmapRequest)){
            requestQueue.add(bitmapRequest);
        }
    }




}
最后对BitmapRequest 封装下
public class Glide {
    public static BitmapRequest with(Context context){
        return new BitmapRequest(context);
    }
}




public interface RequestListenner {

    boolean onSuccess(Bitmap bitmap);

    boolean onFailure();

}

相关文章

网友评论

      本文标题:简单仿写Glide框架

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