手写简易版本Glide

一、源码分析

with主线:
1、给我们build了一个Glide对象(GlideBuilder里返回)
2、给我们创建了空的Fragment
3、把声明周期方法传导出去,谁实现了lifecycle,谁就能操作生命周期
load主线:传入参数,构建出RequestBuilder对象
into主线:运行队列 等待队列 活动缓存 内存缓存 网络模型

二、手写自己的图片加载

步骤一、生命周期的实现

1、创建一个空的Fragment
2、绑定声明周期和接口

先创建绑定生命周期接口类和声明周期接口类

public interface LifeCycle {
    void addListener(@NonNull LifeCycleListener listener);

    void removeListener(@NonNull LifeCycleListener listener);
}
public interface LifeCycleListener {

    void onStart();

    void onStop();

    void onDestroy();
}

创建LifeCycle的实现类ActivityFragmentLifeCycle

public class ActivityFragmentLifeCycle implements LifeCycle {

    // 容器
    private final Set<LifecycleListener> lifecycleListeners =
            Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
    private boolean isStarted;  // 启动的标记
    private boolean isDestroyed; // 销毁的标记

    @Override
    public void addListener(@NonNull LifecycleListener listener) {
        lifecycleListeners.add(listener);

        if (isDestroyed) {
            listener.onDestroy();
        } else if (isStarted) {
            listener.onStart();
        } else {
            listener.onStop();  // 首次启动:会默认 onStop 先停止   然后再onStart
        }
    }

    @Override
    public void removeListener(@NonNull LifecycleListener listener) {
        lifecycleListeners.remove(listener);
    }

    void onStart() {
        isStarted = true;
        for (LifecycleListener lifecycleListener : lifecycleListeners) {
            lifecycleListener.onStart();
        }
    }

    void onStop() {
        isStarted = false;
        for (LifecycleListener lifecycleListener : lifecycleListeners) {
            lifecycleListener.onStop();
        }
    }

    void onDestroy() {
        isDestroyed = true;
        for (LifecycleListener lifecycleListener : lifecycleListeners) {
            lifecycleListener.onDestroy();
        }
    }
}

创建空的(无UI)Fragment,名称跟Glide保持一致,在Fragment的生命周期方法中调用lifecycle的方法以实现绑定

public class RequestManagerFragment extends Fragment {

    private  ActivityFragmentLifeCycle lifecycle = null;
    @Nullable
    private RequestManager requestManager;

    public RequestManagerFragment() {
        this(new ActivityFragmentLifeCycle());
    }

    public RequestManagerFragment(@NonNull ActivityFragmentLifeCycle lifecycle) {
        this.lifecycle = lifecycle;
    }

    public void setRequestManager(@Nullable RequestManager requestManager) {
        this.requestManager = requestManager;
    }

    @NonNull
    public ActivityFragmentLifeCycle getGlideLifecycle() {
        return lifecycle;
    }

    @Nullable
    public RequestManager getRequestManager() {
        return requestManager;
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        // this.lifecycle.addListener(requestManager);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    @Override
    public void onStart() {
        super.onStart();
        lifecycle.onStart();
    }

    @Override
    public void onStop() {
        super.onStop();
        lifecycle.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        lifecycle.onDestroy();
    }
}

因为我们最终要实现这种方式Glide.with(this).load(url).into(iv_image);我们新建一个Glide类,并且写一个with方法,从源码中我们看到with返回的是RequestManager,还有一个RequestManagerRetriever类,用来专门管理RequestManager,并在其get方法中调用了supportFragmentGet方法,这个方法里做了如下操作:
1、从 FragmentManager 中获取 SupportRequestManagerFragment(空白),
2、从该 空白Fragment 中获取 RequestManager
3、如果是首次获取,则实例化,设置 Fragment 对应的 RequestManager
我们也新建一个这样的管理类,实现生命周期方法LifecycleListener,并在构造函数里绑定

public class RequestManagerRetriever implements Handler.Callback {
    static final String FRAGMENT_TAG = "com.bumptech.glide.manager";

    @VisibleForTesting
    final Map<FragmentManager, RequestManagerFragment> pendingSupportRequestManagerFragments =
            new HashMap<>();

    private final Handler handler;

    public RequestManagerRetriever() {
        // 主线程
        handler = new Handler(Looper.getMainLooper(), this);
    }

    private static final int ID_REMOVE_SUPPORT_FRAGMENT_MANAGER = 1; // androidx Fragmetn 空白

    private volatile RequestManager applicationManager;
    @NonNull
    private RequestManager getApplicationManager(@NonNull Context context) {
        if (applicationManager == null) {
            synchronized (this) {
                if (applicationManager == null) {

                    Glide glide = Glide.get(context.getApplicationContext());
                    applicationManager =  RequestManager.getInstance(new ApplicationLifecycle(), context.getApplicationContext());
                }
            }
        }
        return applicationManager;
    }

    // 参数 Context Activity FragmentActivity ... 调用了 此get函数【共用的】
    @NonNull
    public RequestManager get(@NonNull Context context) {
        if (context == null) {
            throw new IllegalArgumentException("你个货,传入的是 空的 context,要把你吊起来打...");
        } else if (Util.isOnMainThread() && !(context instanceof Application)) {
            if (context instanceof FragmentActivity) {
                return get((FragmentActivity) context); // 进入FragmentActivity的get函数
            } else if (context instanceof Activity) {
                return get((Activity) context); // 进入Activity的get函数
            } else if (context instanceof ContextWrapper && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
                return get(((ContextWrapper) context).getBaseContext()); // 继续递归寻找 匹配合适的
            }
        }

        // 若上面的判断都不满足,就会执行下面这句代码,同学们想知道Application作用域 就需要关心这句代码(红色区域)
        return getApplicationManager(context);
    }

    @NonNull
    public RequestManager get(@NonNull FragmentActivity activity) {
        if (Util.isOnBackgroundThread()) {
            return get(activity.getApplicationContext());
        } else {
            Util.assertNotDestroyed(activity);
            FragmentManager fm = activity.getSupportFragmentManager();
            return supportFragmentGet(activity, fm);
        }
    }

    @NonNull
    public RequestManager get(@NonNull Fragment fragment) { // androidx
        if (Util.isOnBackgroundThread()) {
            return get(fragment.getContext().getApplicationContext());
        } else {
            FragmentManager fm = fragment.getChildFragmentManager();
            return supportFragmentGet(fragment.getContext(), fm);
        }
    }

    @NonNull
    private RequestManager supportFragmentGet(
            @NonNull Context context,
            @NonNull FragmentManager fm) {

        // 1、从 FragmentManager 中获取 SupportRequestManagerFragment(空白)
        RequestManagerFragment current = getSupportRequestManagerFragment(fm);

        // 2、从该 空白Fragment 中获取 RequestManager
        RequestManager requestManager = current.getRequestManager();

        // 3、首次获取,则实例化 RequestManager
        if (requestManager == null) { // 【同学们注意:这样做的目的是为了  一个Activity或Fragment 只能有一个 RequestManager】

            // 3.1 实例化
            requestManager =  RequestManager.getInstance( current.getGlideLifecycle(), context);

            // 3.2 设置 Fragment 对应的 RequestManager    空白的Fragment<--->requestManager
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }

    // 1、从 FragmentManager 中获取 SupportRequestManagerFragment
    @NonNull
    private RequestManagerFragment getSupportRequestManagerFragment(
            @NonNull final FragmentManager fm) {
        RequestManagerFragment current =
                (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);

        if (current == null) {

            //  1.2 尝试从【记录保存】中获取 Fragment
            current = pendingSupportRequestManagerFragments.get(fm);

            // 1.3 实例化 Fragment
            if (current == null) {

                // 1.3.1 创建对象 空白的Fragment
                current = new RequestManagerFragment();  // 重复创建

                // 1.3.2 【记录保存】映射关系 进行保存   第一个保障
                // 一个MainActivity == 一个空白的SupportRequestManagerFragment == 一个RequestManager
                pendingSupportRequestManagerFragments.put(fm, current);

                // 1.3.3 提交 Fragment 事务
                fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();

                // 1.3.4 post 一个消息
                handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
            }
        }
        return current;
    }

    @Override
    public boolean handleMessage(Message message) {

        switch (message.what) {
            case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER: // 移除 【记录保存】  1.3.5 post 一个消息
                FragmentManager supportFm = (FragmentManager) message.obj;
                pendingSupportRequestManagerFragments.remove(supportFm); // 1.3.6 移除临时记录中的映射关系
                break;
            default:
                break;
        }

        return false;
    }
}
public class RequestManager implements LifecycleListener {
    private static final String TAG = "RequestManager.class";
    private static RequestManager requestManager;

    private final TargetTracker targetTracker = new TargetTracker();

    private DefaultConnectivity defaultConnectivity;

    private LifeCycle lifecycle;

    private Context mContext;
    private RequestManager(LifeCycle lifecycle, Context context) {
        this.mContext = context;
        this.lifecycle = lifecycle;
        this.lifecycle.addListener(this); // 构造函数 已经给自己注册了【自己给自己绑定】
        defaultConnectivity = new DefaultConnectivity(context);
        this.lifecycle.addListener(defaultConnectivity); // 网络广播注册

    }
    public static RequestManager getInstance(LifeCycle lifecycle, Context context) {

        if (requestManager == null) {
            synchronized (RequestManager.class) {
                if (requestManager == null) {
                    requestManager = new RequestManager(lifecycle,context);
                }
            }
        }

        return requestManager;
    }

    // Activity/Fragment 可见时恢复请求 (onStart() ) 掉用函数
    @Override
    public void onStart() {
        Log.d(TAG, "开始执行生命周期业务 onStart: 运行队列 全部执行,等待队列 全部清空 ....");

        targetTracker.onStart();
        // defaultConnectivity.onStart(); 不需要
    }

    // Activity/Fragment 不可见时暂停请求 (onStop() ) 掉用函数
    @Override
    public void onStop() {
        Log.d(TAG, "开始执行生命周期业务 onStop: 运行队列 全部停止,把任务都加入到等待队列 ....");

        targetTracker.onStop();
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "开始执行生命周期业务 onDestroy: 自己负责移除自己绑定的生命周期监听,释放操作 ....");
        this.lifecycle.removeListener(this); // 已经给自己销毁了 【自己给自己移除】

        targetTracker.onDestroy();

        this.lifecycle.removeListener(defaultConnectivity); // 网络广播注销
    }


    // 链式调度
    // 加载url
    public RequestBuilder load(String url) {

        return new RequestBuilder(mContext).load(url);
    }

    // 链式调度
    // 加载url
    public RequestBuilder load(Uri uri) {

        return new RequestBuilder(mContext).load(uri);
    }


    // 链式调度
    // 加载url
    public RequestBuilder load(File file) {

        return new RequestBuilder(mContext).load(file);
    }
}

至此,我们就完成了with方法的调用

步骤二 构建出RequestBuilder对象

从源码中看,load方法返回了一个RequestBuilder,这个对象主要对参数进行一些操作,真正load交给engine引擎,引擎我们待会再说,先贴出简易版的RequestBuilder的代码

public class RequestBuilder {
    //路径
    // 请求路径
    private String url;

    // 上下文
    private Context context;

    private RequestOptions requestOptions;

    // 回调对象
    private RequestListener requestListener;

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

    public void into(ImageView imageView){
        //glide 99%在into方法实现的
        //不需要传imageView,而是传target
        final ImageViewTarget imageViewTarget = new ImageViewTarget(imageView);
        imageView.setImageResource(requestOptions.getResId());
        Engine.getInstance().into(requestOptions,imageViewTarget);

    }

    public RequestBuilder apply(RequestOptions requestOptions){
        this.requestOptions=requestOptions;
        return this;
    }

    public RequestBuilder load(String url){
        //真正load交给engine引擎
        Engine.getInstance().load(url,context);
        return this;
    }

    public RequestBuilder load(Uri uri){
        //真正load交给engine引擎
        Engine.getInstance().load(uri,context);
        return this;
    }

    public RequestBuilder load(File file){
        //真正load交给engine引擎
        Engine.getInstance().load(file,context);
        return 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 RequestListener getRequestListener() {
        return requestListener;
    }

    public void setRequestListener(RequestListener requestListener) {
        this.requestListener = requestListener;
    }
}

步骤三 缓存处理

三个缓存,活动缓存、内存缓存和磁盘缓存
其中,活动缓存简单来说就是一个map,在当前页有效,当关闭了Activity,则释放活动缓存,并put到内存缓存。
内存缓存继承了LRU算法,当缓存达到上线,则最早放进来的就会被最先释放
磁盘缓存,非运行时缓存,当APP进程被杀掉,依然存在 。而另外两个是运行时缓存,进程杀死就不存在了。源码的磁盘缓存使用了DiskLruCache,我也是如此
活动缓存:

public class ActiveCache {
    private Map<String, Value> mapList = new HashMap<>();
    private com.gaos.glide.glide.resource.ValueCallback valueCallBack;

    public ActiveCache(ValueCallback valueCallBack) {
        this.valueCallBack = valueCallBack;
    }

    /**
     * TODO 添加 活动缓存
     */
    public void put(String key, Value value) {
        Tool.checkNotEmpty(key); // key 不能为空

        // 每次put的时候 put进来的Value 绑定到 valueCallback
        value.setCallBack(this.valueCallBack);

        // 存储 --> 容器
        mapList.put(key, value);
    }

    /**
     * TODO 给外界获取Value
     */
    public Value get(String key) {
        Value value = mapList.get(key);
        if (null != value) {
            return value; // 返回容器里面的 Value
        }
        return null;
    }

    public void deleteActive(String key){
        if(mapList!=null) {
            mapList.remove(key);
        }
    }

}

内存缓存:
LRUCache自带put get等方法 所以不用自己写了

public class MemoryCache extends LruCache<String, Value> {

    public MemoryCache(int maxSize) {
        super(maxSize);
    }

    /**
     * bitmap的大小
     * @param key
     * @param value
     * @return
     */
    @Override
    protected int sizeOf(String key, Value value) {
        int sdkInt = Build.VERSION.SDK_INT;

        if(sdkInt>=Build.VERSION_CODES.KITKAT){
            return value.getmBitmap().getAllocationByteCount();
        }
        return value.getmBitmap().getByteCount();
    }
}

磁盘缓存:

public class DiskBitmapCache implements BitmapCache{

    private DiskLruCache diskLruCache;
    private static volatile DiskBitmapCache instance;
    private int maxDiskSize = 50 * 1024 *1024;
    private String imageCachePath = "image";
    private File file;
    private Context context;
    //单例
    public static DiskBitmapCache getInstance(Context context) {
        if (instance == null) {
            synchronized (DiskBitmapCache.class) {
                if (instance == null) {
                    instance = new DiskBitmapCache(context);
                }
            }
        }
        return instance;
    }

    //创建构造方法时,对DiskLruCache初始化,open

    private DiskBitmapCache(Context context){
        File file = getImageCacheFile(context,imageCachePath);
        this.file = file;
        if(!file.exists()){
            file.mkdirs();
        }
        this.context = context;
        //第一个传文件夹(私有目录的文件夹),app版本号,对应值数量,单个文件支持的最大大小
        try {

            diskLruCache = DiskLruCache.open(file,getAppVersion(context),1,maxDiskSize);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    //获取版本号
    private int getAppVersion(Context context) {
        //获取包管理器
        PackageManager pm = context.getPackageManager();
        //获取包信息
        try {
            PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
            //返回版本号
            return packageInfo.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 0;
    }




    //获取图片文件
    private File getImageCacheFile(Context context, String imageCachePath) {
        String path;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            path = context.getExternalCacheDir().getPath();
        } else {
            path = context.getCacheDir().getPath();
        }
        return new File(path + File.separator + imageCachePath);
    }


    /**
     *
     * @param key
     * @param value
     */
    @Override
    public void put(String key, Value value) {
        DiskLruCache.Editor editor =null;
        OutputStream outputStream = null;
        try {
            if(diskLruCache.isClosed()){
                diskLruCache = DiskLruCache.open(file,getAppVersion(context),1,maxDiskSize);
            }
            editor = diskLruCache.edit(key);
            if(editor!=null) {
                outputStream = editor.newOutputStream(0);
                Bitmap bitmap = value.getmBitmap();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
                outputStream.flush();
            }
        } catch (IOException e) {
           e.printStackTrace();
        }finally {
            try {
                if(editor!=null) {
                    editor.commit();
                }
                if(diskLruCache.isClosed()){
                    diskLruCache = DiskLruCache.open(file,getAppVersion(context),1,maxDiskSize);
                }
                diskLruCache.close();
                if(outputStream!=null){
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public Value get(String key) {
        Value value = new Value();
        InputStream inputStream = null;
        try {
            if(diskLruCache.isClosed()){
                diskLruCache = DiskLruCache.open(file,getAppVersion(context),1,maxDiskSize);
            }
            DiskLruCache.Snapshot snapshot = diskLruCache.get(key);
            if(snapshot==null){
                return null;
            }
             inputStream = snapshot.getInputStream(0);
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            value.setmBitmap(bitmap);
            value.setKey(key);
            return value;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(inputStream!=null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    @Override
    public void remove(String key) {
        try {
            diskLruCache.remove(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

步骤四 Engine引擎

主要操作就是读取缓存,而从网络加载图片则分发给EngineJob处理
EngineJob实现Runnable方法,执行线程
读取逻辑是先找活动缓存,没有就找内存缓存,没有就去找磁盘缓存,在没有找服务器
从网络加载的图片首先放到活动缓存,在放到内存缓存
图片加载时,来自活动缓存,则从活动缓存移除放到内存缓存
来自内存缓存则从内存缓存移除放到活动缓存
来自磁盘缓存则放到活动缓存,移除内存缓存
总之,存储只缓存2份

public class Engine implements ValueCallback,ResponseListener{
    private static final String TAG = "Engine";
    /**
     * 1、读缓存(1级,2级,3级),读取逻辑
     * 2、分发给EngineJob
     */
    private Context glideContext;
    private String path;
    private String key;
    private ActiveCache activeCache; // 活动缓存
    private MemoryCache memoryCache; // 内存缓存
    private DiskBitmapCache diskLruCache; // 磁盘缓存
    private final int MEMORY_MAX_SIZE = 1024*1024*120;
    private static Engine engine;
    RequestOptions requestOptions;
    ImageViewTarget imageViewTarget;

    public static Engine getInstance(){
        if(engine==null){
            engine = new Engine();
        }
        return engine;
    }

    private Engine(){
        if (activeCache == null) {
            activeCache = new ActiveCache(this); // 回调给外界,Value资源不再使用了 设置监听
        }
        if (memoryCache == null) {
            memoryCache = new MemoryCache(MEMORY_MAX_SIZE); // 内存缓存
        }
    }


    public void load(String path,Context context){
        this.path = path;
        this.glideContext = context;
        this.key = new Key(path).getKey();
        diskLruCache = DiskBitmapCache.getInstance(glideContext);
    }

    public void load(Uri uri, Context context){
        this.path = uri.getPath();
        this.glideContext = context;
        this.key = new Key(path).getKey();
        diskLruCache = DiskBitmapCache.getInstance(glideContext);
    }

    public void load(File file, Context context){
        this.path = file.getAbsolutePath();
        this.glideContext = context;
        this.key = new Key(path).getKey();
        diskLruCache = DiskBitmapCache.getInstance(glideContext);
    }

    //读取缓存方法
    public void into(RequestOptions requestOptions, ImageViewTarget imageViewTarget){
        Tool.assertMainThread();
        this.requestOptions = requestOptions;
        //如果本地缓存有,就直接渲染
        Value value = cacheAction(imageViewTarget);//
        this.imageViewTarget = imageViewTarget;
        if(value!=null){
            Bitmap bitmap = value.getmBitmap();
            Matrix matrix = new Matrix();
            if(bitmap!=null) {
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, requestOptions.getWidth(), requestOptions.getHeight(), matrix, true);

            imageViewTarget.setResource(bitmap);
            }
        }
    }

    private Value cacheAction(ImageViewTarget imageViewTarget){
        //判断读取逻辑,1级缓存-活动缓存有,没有就找内存缓存,没有就去找磁盘缓存,找服务器
        Value value = activeCache.get(key);
        if(value!=null){
            Log.w(TAG,"1111--我是来自于活动缓存的数据");
            //发现活动缓存有,就可以在这里设置进去
            memoryCache.put(key,value);
            //-------------
            //1、发现活动缓存有,就放到内存缓存,然后移除活动缓存
            //2、服务器去获取
            //3、RequestBuilder
            //4、ImageViewTarget
            activeCache.deleteActive(key);
            return value;
        }
         value = memoryCache.get(key);
        if(value!=null){
            // 移动操作 剪切(内存--->活动)
            activeCache.put(key, value); // 把内存缓存中的元素,加入到活动缓存中...
            memoryCache.remove(key); // 移除内存缓存
            Log.w(TAG,"1111--我是来自于内存缓存的数据");
            return value;
        }
        value = diskLruCache.get(key);
        if(value!=null){
            Log.w(TAG,"1111--我是来自于磁盘缓存的数据");
            //磁盘缓存中有,就放到活动缓存,然后移除内存缓存
            activeCache.put(key,value);
            memoryCache.remove(key);
            //真正的glide  key(path,width,height,签名),UUID
            return value;
        }

        //服务器去找
        //--------------------
        new EngineJob().loadResource(path,this,glideContext,imageViewTarget,requestOptions);

        return null;
    }


    //写缓存


    @Override
    public void valueNonUseListener(String key, Value value) {

    }

    @Override
    public void responseSuccess(String key, Value value) {
        Log.d(TAG, "saveCache: >>>>>>>>>>>>>>>>>>>>>>>>>> 加载外置资源成功后 ,保存到缓存中, key:" + key + " value:" + value);
        value.setKey(key);
        if (diskLruCache != null) {
            activeCache.put(key, value);  //这个无所谓 自由控制了
            //这里不需要放内存缓存
            diskLruCache.put(key, value); // 保存到磁盘缓存中....
        }
    }

    @Override
    public void responseException(Exception e) {

    }
}
public class EngineJob implements Runnable{
    private String path;
    private ResponseListener responseListener;
    private Context context;
    RequestOptions requestOptions;
    private ImageViewTarget imageViewTarget;
    public Value loadResource(String path, ResponseListener responseListener, Context context, ImageViewTarget imageViewTarget, RequestOptions requestOptions){
        //执行线程,线程池
        this.path = path;
        this.responseListener = responseListener;
        this.context = context;
        this.imageViewTarget = imageViewTarget;
        this.requestOptions = requestOptions;
        Uri uri = Uri.parse(path);
        if("HTTP".equalsIgnoreCase(uri.getScheme())||"HTTPS".equalsIgnoreCase(uri.getScheme())){
            ThreadPoolManager.getInstance().execute(this);
        }else{
            //区分本地还是网络
            Bitmap bitmap = BitmapFactory.decodeFile(path);
            Value value = new Value();
            value.setmBitmap(bitmap);
            String key = new Key(path).getKey();
            value.setKey(key);
            imageViewTarget.setResource(bitmap);
            responseListener.responseSuccess(key,value);
        }
        return null;
    }
    @Override
    public void run() {
        //第三方Glide做了很多步,这里就一步做了
        //这里就去做接口请求,由子线程直接转为主线程
        final Bitmap bitmap = getImageBitmap(path);
        Executor executor = new MainThreadExecutor();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                Value value = new Value();
                Log.w("EngineJob","1111--我是来自于服务器获取的数据");
                value.setmBitmap(bitmap);
                String key = new Key(path).getKey();
                responseListener.responseSuccess(key,value);

                imageViewTarget.setResource(bitmap);
            }
        });

    }


    private Bitmap getImageBitmap(String url){
        Bitmap bitmap=null;
        HttpURLConnection conn = null;
        InputStream is = null;
        try {
            URL imageUrl = new URL(url);
            //要用到HttpURLConnection
            conn = (HttpURLConnection) imageUrl.openConnection();
            conn.connect();
             is = conn.getInputStream();
            //Bitmap工厂类,流转化成Bitmap
            bitmap = BitmapFactory.decodeStream(is);
            Matrix matrix = new Matrix();
            bitmap =  Bitmap.createBitmap(bitmap,0,0,requestOptions.getWidth(), requestOptions.getHeight(), matrix,true);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(is!=null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null) {
                conn.disconnect();
            }
        }
        return bitmap;
    }
}

源码地址:
https://github.com/gaoscxy/Glide

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值