Glide源码解读之绑定生命周期

Glide(一)生命周期绑定 Glide 的解耦方式很独特。 1.1 Glide.with() Glide.with(FragmentActivity activity) // RequestManager with(FragmentActivity activity)public static RequestManager with(Activity activity) { return getRetriever(ac 阅读详情

今天有空,稍微解读了一下glide加载图片框架源码,glide源码比较多,除了弄清楚主流程,对我编程有帮助的,我都会记录下来。

我这里不会一步一步详细解读源码,因为其他博客一大堆,我这里主要讲解一下原理;

绑定生命周期,不用我们自己在onStart,onStop去调用,这种思想很好,所以,值得借鉴。

主要实现原理是创建一个无UI的Fragment添加(绑定)到当前的Activity(或其他Fragment),通过重写Fragment的onStart和onStop方法,通知RequestManager任务改变状态。

源码如下:

外观类:RequestManagerRetriever

package com.johan.glide;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

import java.util.HashMap;
import java.util.Map;

public class RequestManagerRetriever implements Handler.Callback {

    private static RequestManagerRetriever instance;

    public static RequestManagerRetriever getInstance() {
        if (instance == null) {
            synchronized (RequestManagerRetriever.class) {
                if (instance == null) {
                    instance = new RequestManagerRetriever();
                }
            }
        }
        return instance;
    }

    private Map<FragmentManager, RequestManagerFragment> tempMap;
    private Handler handler;

    public RequestManagerRetriever() {
        tempMap = new HashMap<>();
        handler = new Handler(Looper.getMainLooper(), this);
    }

    public RequestManager getRequestManager(FragmentActivity fragmentActivity) {
        return getRequestManager(fragmentActivity.getSupportFragmentManager());
    }

    public RequestManager getRequestManager(Fragment fragment) {
        return getRequestManager(fragment.getChildFragmentManager());
    }

    private RequestManager getRequestManager(FragmentManager fragmentManager) {
        // 从 FragmentManager 通过 tag 获取 Fragment
        RequestManagerFragment managerFragment = (RequestManagerFragment) fragmentManager.findFragmentByTag("com.johan.glide");
        if (managerFragment == null) {
            // 从临时缓存获取 Fragment
            // 为什么要用到临时缓存呢?
            // 比如连续两次调用 getRequestManager 方法
            // 因为 fragmentManager.beginTransaction().add(managerFragment, "com.johan.glide").commitAllowingStateLoss(); 这句代码执行之后呢
            // 创建的 Fragment 不会马上能被 fragmentManager.findFragmentByTag("com.johan.glide") 找到
            // 防止重复添加到 FragmentManager
            managerFragment = tempMap.get(fragmentManager);
            if (managerFragment == null) {
                // 创建
                managerFragment = new RequestManagerFragment();
                // 加入临时缓存
                tempMap.put(fragmentManager, managerFragment);
                // 添加到 FragmentManager
                fragmentManager.beginTransaction().add(managerFragment, "com.johan.glide").commitAllowingStateLoss();
                // 通知移除临时缓存
                handler.obtainMessage(0, fragmentManager).sendToTarget();
            }
        }
        // 先从 RequestManagerFragment 获取 RequestManager
        RequestManager manager = managerFragment.getRequestManager();
        if (manager == null) {
            // 创建
            manager = new RequestManager(managerFragment.getActivityLifeCycle());
            // 设置
            managerFragment.setRequestManager(manager);
        }
        return manager;
    }

    @Override
    public boolean handleMessage(@NonNull Message message) {
        //  移除临时缓存
        tempMap.remove((FragmentManager) message.obj);
        return true;
    }

}

无 UI Fragment:RequestManagerFragment

package com.johan.glide;

import android.util.Log;

import androidx.fragment.app.Fragment;

public class RequestManagerFragment extends Fragment {

    private ActivityLifeCycle activityLifeCycle;
    private RequestManager requestManager;

    public RequestManagerFragment() {
        activityLifeCycle = new ActivityLifeCycle();
    }

    public ActivityLifeCycle getActivityLifeCycle() {
        return activityLifeCycle;
    }

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

    public RequestManager getRequestManager() {
        return requestManager;
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.e("glide", "RequestManagerFragment onStart --------- ");
        // 生命周期回调
        if (activityLifeCycle != null) {
            activityLifeCycle.onStart();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.e("glide", "RequestManagerFragment onStop --------- ");
        // 生命周期回调
        if (activityLifeCycle != null) {
            activityLifeCycle.onStop();
        }
    }

}

生命周期监听接口:LifeCycleListener

public interface LifeCycleListener {

    void onStart();

    void onStop();

}

生命周期接听接口管理者:ActivityLifeCycle

package com.johan.glide;

import java.util.ArrayList;
import java.util.List;

public class ActivityLifeCycle implements LifeCycleListener {

    private List<LifeCycleListener> lifeCycleListeners;

    public ActivityLifeCycle() {
        lifeCycleListeners = new ArrayList<>();
    }

    public void addLifeCycleListener(LifeCycleListener lifeCycleListener) {
        lifeCycleListeners.add(lifeCycleListener);
    }

    public void removeLifeCycleListener(LifeCycleListener lifeCycleListener) {
        lifeCycleListeners.remove(lifeCycleListener);
    }

    @Override
    public void onStart() {
        for (LifeCycleListener lifeCycleListener : lifeCycleListeners) {
            lifeCycleListener.onStart();
        }
    }

    @Override
    public void onStop() {
        for (LifeCycleListener lifeCycleListener : lifeCycleListeners) {
            lifeCycleListener.onStop();
        }
    }

}

任务管理者:RequestManager

package com.johan.glide;

import android.util.Log;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class RequestManager implements LifeCycleListener {

    private ExecutorService executorService;
    private Future future;

    public RequestManager(ActivityLifeCycle activityLifeCycle) {
        executorService = Executors.newCachedThreadPool();
        // 监听生命周期
        activityLifeCycle.addLifeCycleListener(this);
    }

    /**
     * 模拟耗时操作
     */
    public void execute() {
        future = executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 100; i++) {
                        Log.e("glide", this + " execute " + i);
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void onStart() {
        Log.e("glide", "request start --------------");
    }

    @Override
    public void onStop() {
        Log.e("glide", "request stop --------------");
        // 停止耗时操作
        future.cancel(true);
        executorService.shutdown();
    }

}

我想可以用这种思想带到我们平常在Activity执行耗时操作中,这样我们的耗时操作就可以和我们的Activity生命周期一样,避免内存泄漏!!!

这里先做一个记录,继续分析glide源码!!!!!

深入理解Glide源码:三条主线分析-Glide-执行流程 Glide流程分析 说到图片加载框架,大家最熟悉的莫过于Glide了,但我却不推荐简历上写熟悉Glide, 除非你熟读它的源码,或者参与Glide的开发和维护。然而很多小伙伴对于Glide的流程及其源码解读总是无从下手,本篇就从三条主线来分析一下Glide流程及源码! 第一条主线 加入队列流程: RequestManager with = Glide.with(this); RequestBuilder<Drawable> load = with.load(url); load.into(iv) 阅读详情

相关推荐

CustomGlideLifecycleDemo:仿Glide框架,自定义Lifecycle框架,实现绑定页面生命周期

如何绑定页面生命周期(一)-Glide实现 Glide中一个重要的特性,就是Request可以随着Activity或Fragment的onStart而resume,onStop而pause,onDestroy而clear。从而节约流量和内存,并且防止内存泄露,这一切都由Glide在内部实现了。用户唯一要注意的是,Glide.with()方法中尽量传入Activity或Fragment,而不是Application,不然没办法进行生命周期管理。 因为对Glide绑定生命周期的原理很感兴趣,所以看了一些源码解析的文章,也读了Glide的相关源码。发现大多数对于Glide生命周期绑定原理的介绍,是直接通过源码一步步的介绍。个人感觉这样没有重点,容易迷失在代码流程细节中。 所以这篇文章通过另外一种方式介绍Glide生命周期管理的原理,即通过提问解答的方式,带着问题阅读,更加具有针对性。介绍完了原理

面试之Glide如何绑定Activity的生命周期

整个流程调用Glide.with时首先获取到Glide单例中的RequestManagerRetriever,再调用retriever的get(),再他的get方法中创建了一个无界面的Fragment并且注册给Activity,然后将这个Fragment里面的LifeCycle传递给要返回的RequestManager,在这个RequestManager中给LifeCycle注册了一个观察者,这样就完成了生命周期在Activity->Fragment->RequestManager之间的传递;

weixin_43243916的博客 972

Python自动化车载测试:5分钟搞定CANoe COM接口调用(附完整代码)

本文详细介绍了如何使用Python快速实现CANoe COM接口调用,完成车载测试自动化。通过实战案例展示ECU信号测试框架搭建,包括环境配置、核心架构解析、信号读写封装及多线程安全方案,帮助开发者5分钟内掌握高效测试技巧。

vv45678的博客 1133

Glide源码解析2 -- 生命周期原理

一 概述 Glide 中一个重要的特性就是Request可以绑定Activity或者fragment的onStart而resume,onStop而pause,onDestroy而clear,所以Glide可以节约流量内存,防止内存泄露,但是要注意不要传入在with()方法里传入application,不然就没办法对生命周期进行管理了。 二 核心类 RequestManager:实现了LifeCycleListener,主要作用是结合Activity或者Fragment的生命周期,对Request进行管理,

qq_39431405的博客 1916

FLUKA软件在Ubuntu的安装指南(亲测有效)

FLUKA其强大的蒙特卡洛模拟能力使得用户能够模拟复杂的辐射相互作用过程

chencheng1127的博客 2887

避坑指南:STM32CubeMX配置SDIO4bit模式时为什么卡在HAL_SD_ConfigWideBusOperation?

本文深入分析了使用STM32CubeMX配置SDIO 4位模式时,程序在HAL_SD_ConfigWideBusOperation函数处卡死的常见问题。文章从硬件连接、CubeMX配置、初始化序列及HAL库底层实现等多个维度剖析根源,并提供了从初始化流程优化到增强代码鲁棒性等实战解决方案,帮助开发者彻底解决这一棘手难题。

pca5navigator的博客 825

Glide生命周期绑定

Glide.class和RequestManagerRetriever.class,主要用来获得RequestManager //with返回一个RequestManager public static RequestManager with(Activity activity) { return getRetriever(activity).get(activity); } //无论调用的是哪个with重载方法,最后都会到这里 public RequestManager get(Activit

678

Qlib上手学习记录

Qlib 是一个面向人工智能的量化投资平台,其目标是通过在量化投资中运用AI技术来发掘潜力、赋能研究并创造价值,从探索投资策略到实现产品化部署。该平台支持多种机器学习建模范式,包括有监督学习、市场动态建模以及强化学习等。真的是走了很多弯路step 1. 使用 ananconda 建立环境,要主要必须是 python 3.8失败的下了以后 进入 glib folder 后执行是会报错的,不管你还什么source 都一样,整了很久使用前最好看下这个。

chenchihwen的专栏 3100

Glide原理--生命周期绑定

Gilde 的使用 最基础的使用 Glide.with(context).load(url).into(imageView) with方法 Glide.with(context) with 重载方法 with(android.app.Activity) with(android.app.Fragment) with(android.support.v4.app.Fragment) with(a...

hjiangshujing的博客 912

CTFShow萌新区全攻略:从密码破解到Web渗透的实战解析

本文为CTFShow萌新区新手提供从密码破解到Web渗透的完整实战攻略。文章深入解析了密码学、隐写术、杂项和Web安全四大核心方向,分享了实用的解题工具、思维方法和绕过技巧,旨在帮助初学者建立系统的安全竞赛解题体系,而不仅仅是提供一份题解(WP)。

weixin_29216957的博客 299

车载以太网-TC8测试

TC8测试的用例数量 TC8测试基本流程 TC8测试内容

天赐好车的博客 3619

简述Glide的源码

Glide 的源码设计精巧,通过分层架构和各种优化策略,实现了高效、灵活、可靠的图片加载功能。它的缓存机制、生命周期绑定和丰富的功能使得它成为 Android 开发中非常受欢迎的图片加载库。的生命周期绑定,确保在合适的时候自动暂停和恢复图片加载请求,避免内存泄漏和资源浪费。类:负责将获取到的图片数据解码为可显示的图片格式。实例,该实例负责管理特定上下文的图片加载请求。类:这是 Glide 的入口类,提供了。类:管理特定上下文的图片加载请求。类:用于构建具体的图片加载请求。类:图片加载的核心引擎。

challenge51all的专栏 1908

AMBA-CHI协议详解(二)

读事务,写事务,原子事务,Stash事务,Dataless事务,DVM事务,Retry事务。

Crazzy_M的博客 6656

Glide v4 源码浅析(1)-with

文章目录@[toc]简述源码Glide初始化 简述 Glide为Android平台下的图片加载框架,它的使用方法可以查看教程文档。 这里从一个最简单的使用实例入手,分析glide源码调用过程(使用的glide版本为v4.8.0): Glide.with(activity) .load(imgUrl) .into(imageView); 本例实现了在一个FragmentActi...

chidh的博客 297

5、癌症数据预处理技术与深度学习在癌症预测中的应用

本文详细介绍了癌症数据预处理技术和深度学习在癌症预测中的应用。针对CT扫描图像、X射线图像、超声图像、基因表达数据和文本数据等不同类型的癌症数据,分别阐述了去噪、插值、配准、归一化等预处理技术的具体方法。同时,分析了深度学习在乳腺癌、白血病和宫颈癌预测中的作用,结合相关影响因素探讨了模型的应用潜力。此外,还总结了深度学习在癌症预测中面临的挑战及未来发展方向,为癌症的早期诊断与精准预测提供了理论支持和技术参考。

alice7model的博客 123

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Glide源码&缓存策略分析

Glide源码分析 前言 本文分析基于Glide 4.10.0,若有错误疏漏之处,请各位大佬指正。 基本使用 Glide.with(this).load(strUrl).into(imageView); with(Context context)方法 Glide中的这些with的构造方法会绑定传入对象的生命周期,但是为什么要这么做呢? 因为退出一个页面时,如果此时还在加载图片,就可能会发生内存泄漏,所以就需要Glide在退出页面时取消加载请求,防止内存泄漏。 @NonNull public s

qq_43935080的博客 617

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Glide的特点、使用、原理、源码解读和要注意的问题。

Glide的特点、使用、原理、源码解读、开发中要注意的问题。

challenge51all的专栏 941

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Android 架构之Glide源码解读(中)

前言 在上一篇中,主要讲解了Glide 基础知识点以及with、load、into这三部曲中的with,知道了在with中Glide主要帮我们做了生命周期相互绑定的相关工作。在这一篇中,将会对load、into进一步解读相应的源码。 本篇解读的源码版本:4.11.0,读者也可以根据本章步骤,在AS中一步一步解读源码。 1、load 方法 @NonNull @CheckResult @Override public RequestBuilder<Drawable> load(@Nu

qq_30382601的博客 367

Glide 源码解读

目录导读三大主流图片框架对比 导读   时隔将近半个月,又到了要学习源码的时候。那么这里我最近就Glide进行一个源码的解读。至于为什么选择Glide进行源码解读,我们开始会就目前三大主流的图片框架进行简要比较,然后根据Glide的三大方法(with,load,into)进行源码解读,再在源码的层面上进行分析,发现一些Glide的其他神奇用法,那么闲话不多说,直接开始吧! 三大主流图片框架对比   再说主流框架之前,先提一个老伙计,也就是Universal ImageLoader,这是由白俄罗斯的Serge

number_cmd9的博客 655

Glide(一)生命周期的监听

Glide对生命周期的监听

qq_41095045的博客 1405

Android 架构之Glide源码解读(下)

前言 在前两篇中,主要进行了 Glide 三部曲 with、load、into 对应的源码解析。在本篇中将会对Glide的三级缓存以及三层缓存实现的逻辑进行详解。 在解读三级缓存之前,我们先熟悉其原理,然后再将其原理带入源码中解读,将会事半功倍。 所谓的 如图所示 ...

qq_30382601的博客 323

深入剖析 Glide:加载流程与生命周期管理的艺术

本文将不仅仅停留在 API 调用层面,而是深入 Glide 的源码腹地,揭秘其图片加载的完整流程以及如何优雅地绑定生命周期以实现“自动化”的内存管理。通过深入理解 Glide 的加载流程和生命周期管理机制,我们不仅能更好地使用这个强大的工具,还能从中学习到优秀库的设计思想,写出更健壮、高效的 Android 代码。: 配置这次加载请求的“蓝图”,包括数据模型(URL、URI等)、转换选项、占位符、错误图等。: 启动请求,经历加载、解码、转换、缓存、设置图片等一系列操作,最终将图片显示到。

专注于移动开发的干货分享。提供高效解决方案、避坑指南与前沿技术解析。为开发者创造价值。 910

深入解析Glide

在深入了解Glide之前,我们要先来认识一下Glide到底是什么,不要只知道他是图片处理框架,只会其简单的使用,只知道这些是不够的,因为学东西就是要刨根问底,学以致用。今天我们就带着这样几个问题来学习Glide。Glide是什么?Glide的实现原理是什么?Glide对比其他图片加载框架有什么优缺点(也就是为什么要使用Glide)? 自己如何设计一款图片加载框架? Glide是什么? 1.Glide是什么? Glide是Google在2014的IO大会发布一款图片处理框架,是目前android领域比较成熟的

hirezy 7879

Glide源码分析(一)从用法来看之with方法

继续啃源码,用过Glide的人,肯定都觉得它好好用,我们一般只需要几行代码,就可以达到我们想要的效果,可以在这个背后是什么呢?就需要我们来看了。 我一般看源码,我喜欢先从用法来看,然后一步一步的再细扣,所以就先从用法来看Glide的整体流程。 用过Glide的人,用下面这段代码,就可以进行图片的加载: Glide.with(this) .load(url) ...

小薇子的博客 634

Android Glide源码解读(一) : 主流程分析

本篇作为史上最细**Glide源码解读系列第一篇** , 主要对主流程进行分析 以后还会有若干篇对Glide 中 运用的设计模式 / 线程池 /图片优化/ 解码/转码/缓存 等细节的文章发布

Eqiqi的博客 911

Glide源码浅析

以下glide源码基于库上最新的4.11版本, 以下很多代码没有写中间的层层调用,因为层级太多了,感兴趣的可以自己通过debugu模式或者查看源码去发现。 上一篇文章说到图片缓存的LRU的原理分析,并简单的说了下glide的使用,今天就开门见山,先看最简单的使用示例: Glide.with(this) .load(url).diskCacheStrategy(DiskCacheStrategy.ALL) .error(R.drawable.icon).placeholder(R.drawab.

javaer2012207的博客 374
上一篇: PS 一键生成Android各个尺寸的图标
下一篇: Nacos
JohanMan
博客等级 码龄10年 72粉丝 131原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值