Android-Glide详解

目录

一,介绍

二,使用

三,源码分析思路

四,with源码分析

五,模拟Glide生命周期管理


一,介绍

Glide目前是安卓最主流的加载图片的框架,也是源码最为复杂的框架之一。 要想完完全全吃透Glide的源码,可能需要半年甚至更多的时间。

但是如果分析过Glide的源码,不仅对我们的架构能力有很大提高,也会对面试中的关于Glide的问题知其然更知其所以然。

Glide的精髓,在于它的生命周期的管理和缓存策略。

二,使用

Glide的使用及其简单

java 复制代码
 // 项目的build.gradle添加依赖
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

在清单文件添加网络权限:

java 复制代码
 <uses-permission android:name="android.permission.INTERNET"/>

布局文件很简单就一个imageview:

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         />

</androidx.constraintlayout.widget.ConstraintLayout>

使用:

Kotlin 复制代码
class MainActivity : AppCompatActivity() {
    //图片url
    private val url ="https://q7.itc.cn/q_70/images03/20240714/93ce0113753a4ff4b5f4e48f27ed3739.jpeg"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val iv =findViewById<ImageView>(R.id.iv)
        Glide.with(this).load(url).into(iv)

    }
}

效果:

三,源码分析思路

Glide的源码分析,我们可以从使用角度,拆分为三部分去分析。

java 复制代码
class MainActivity : AppCompatActivity() {
    //图片url
    private val url ="https://q7.itc.cn/q_70/images03/20240714/93ce0113753a4ff4b5f4e48f27ed3739.jpeg"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val iv =findViewById<ImageView>(R.id.iv)
        //第一步 调用with  得到RequestManager
        val requestManager:RequestManager = Glide.with(this)
       
        //第二步 RequestManager调用load 得到requestBulider
        val requestBulider:RequestBuilder<Drawable> =requestManager.load(url)
        
        //第三步 requestBulider调用into
        requestBulider.into(iv)
    }
}

这样拆分的话,思路会比较清晰。

四,with源码分析

首先我们看一下with的源码:

java 复制代码
@NonNull
public static RequestManager with(@NonNull Context context) {
  return getRetriever(context).get(context);
}

@NonNull
public static RequestManager with(@NonNull Activity activity) {
  return getRetriever(activity).get(activity);
}

@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
  return getRetriever(activity).get(activity);
}

@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
  return getRetriever(fragment.getContext()).get(fragment);
}

@SuppressWarnings("deprecation")
@Deprecated
@NonNull
public static RequestManager with(@NonNull android.app.Fragment fragment) {
  return getRetriever(fragment.getActivity()).get(fragment);
}

@NonNull
public static RequestManager with(@NonNull View view) {
  return getRetriever(view.getContext()).get(view);
}

它可以接受的参数类型很多,确保多种场景下的使用

然后继续往下看getRetriever这个函数:

java 复制代码
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  // Context could be null for other reasons (ie the user passes in null), but in practice it will
  // only occur due to errors with the Fragment lifecycle.
  Preconditions.checkNotNull(
      context,
      "You cannot start a load on a not yet attached View or a Fragment where getActivity() "
          + "returns null (which usually occurs when getActivity() is called before the Fragment "
          + "is attached or after the Fragment is destroyed).");
  return Glide.get(context).getRequestManagerRetriever();
}

判空不用看,直接看get(context)这个函数:

java 复制代码
@NonNull
public static Glide get(@NonNull Context context) {
  if (glide == null) {
    GeneratedAppGlideModule annotationGeneratedModule =
        getAnnotationGeneratedGlideModules(context.getApplicationContext());
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context, annotationGeneratedModule);
      }
    }
  }
  return glide;
}

这个就是我们熟悉的双重检测单例模式,不了解的可以参考文章:Android 设计模式--单例模式_android开发饿汉单例-CSDN博客

然后我们看看 checkAndInitializeGlide(context, annotationGeneratedModule):

java 复制代码
@GuardedBy("Glide.class")
private static void checkAndInitializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  // In the thread running initGlide(), one or more classes may call Glide.get(context).
  // Without this check, those calls could trigger infinite recursion.
  if (isInitializing) {
    throw new IllegalStateException(
        "You cannot call Glide.get() in registerComponents(),"
            + " use the provided Glide instance instead");
  }
  isInitializing = true;
  initializeGlide(context, generatedAppGlideModule);
  isInitializing = false;
}

这里好像没有什么具体的信息,我们接着往下看initializeGlide(context,generatedAppGlideModule)这个函数:

java 复制代码
@GuardedBy("Glide.class")
private static void initializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}

好的,依然继续往下看initializeGlide(context, new GlideBuilder(), generatedAppGlideModule)

java 复制代码
@GuardedBy("Glide.class")
@SuppressWarnings("deprecation")
private static void initializeGlide(
    @NonNull Context context,
    @NonNull GlideBuilder builder,
    @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    //获取应用级别的上下文
  Context applicationContext = context.getApplicationContext();
  List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
  if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
    manifestModules = new ManifestParser(applicationContext).parse();
  }
  if (annotationGeneratedModule != null
      && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
    Set<Class<?>> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
    Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
    while (iterator.hasNext()) {
      com.bumptech.glide.module.GlideModule current = iterator.next();
      if (!excludedModuleClasses.contains(current.getClass())) {
        continue;
      }
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
      }
      iterator.remove();
    }
  }
  if (Log.isLoggable(TAG, Log.DEBUG)) {
    for (com.bumptech.glide.module.GlideModule glideModule : manifestModules) {
      Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
    }
  }
//通过注解生成的代码拿到 RequestManagerFactory
  RequestManagerRetriever.RequestManagerFactory factory =
      annotationGeneratedModule != null
          ? annotationGeneratedModule.getRequestManagerFactory()
          : null;
//将拿到的工厂添加到 GlideBuilder
  builder.setRequestManagerFactory(factory);
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
    module.applyOptions(applicationContext, builder);
  }
  if (annotationGeneratedModule != null) {
    annotationGeneratedModule.applyOptions(applicationContext, builder);
  }
//通过 Builder 建造者模式,构建出 Glide 实例对象
  Glide glide = builder.build(applicationContext);
//注册组件回调
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
    try {
      module.registerComponents(applicationContext, glide, glide.registry);
    } catch (AbstractMethodError e) {
      throw new IllegalStateException(
          "Attempting to register a Glide v3 module. If you see this, you or one of your"
              + " dependencies may be including Glide v3 even though you're using Glide v4."
              + " You'll need to find and remove (or update) the offending dependency."
              + " The v3 module name is: "
              + module.getClass().getName(),
          e);
    }
  }
  if (annotationGeneratedModule != null) {
    annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
  }
  applicationContext.registerComponentCallbacks(glide);
//将构建出来的 glide 赋值给 Glide 的静态变量
  Glide.glide = glide;
}

这个函数里面的信息量是非常大的,主要是进行了一系列的初始化操作,通过 Builder 建造者模式,构建出 Glide 实例对象,接着我们看看builder模式进行了哪些构建:

java 复制代码
@NonNull
Glide build(@NonNull Context context) {
//网络请求的线程池
  if (sourceExecutor == null) {
    sourceExecutor = GlideExecutor.newSourceExecutor();
  }
//本地磁盘缓存的线程池
  if (diskCacheExecutor == null) {
    diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
  }
//加载图片动画的一个线程池
  if (animationExecutor == null) {
    animationExecutor = GlideExecutor.newAnimationExecutor();
  }
//对图片加载到内存的一个计算
  if (memorySizeCalculator == null) {
    memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
  }
//默认网络连接监控的工厂
  if (connectivityMonitorFactory == null) {
    connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
  }
//Bitmap 对象池
  if (bitmapPool == null) {
    int size = memorySizeCalculator.getBitmapPoolSize();
    if (size > 0) {
      bitmapPool = new LruBitmapPool(size);
    } else {
      bitmapPool = new BitmapPoolAdapter();
    }
  }
//数组对象池
  if (arrayPool == null) {
    arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
  }
//资源内存缓存
  if (memoryCache == null) {
    memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
  }
//磁盘缓存的工厂
  if (diskCacheFactory == null) {
    diskCacheFactory = new InternalCacheDiskCacheFactory(context);
  }
//构建执行缓存策略跟线程池的引擎
  if (engine == null) {
    engine =
        new Engine(
            memoryCache,
            diskCacheFactory,
            diskCacheExecutor,
            sourceExecutor,
            GlideExecutor.newUnlimitedSourceExecutor(),
            animationExecutor,
            isActiveResourceRetentionAllowed);
  }
  if (defaultRequestListeners == null) {
    defaultRequestListeners = Collections.emptyList();
  } else {
    defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
  }
//RequestManagerRetriever 请求管理类
  RequestManagerRetriever requestManagerRetriever =
      new RequestManagerRetriever(requestManagerFactory);
  return new Glide(
      context,
      engine,
      memoryCache,
      bitmapPool,
      arrayPool,
      requestManagerRetriever,
      connectivityMonitorFactory,
      logLevel,
      defaultRequestOptionsFactory,
      defaultTransitionOptions,
      defaultRequestListeners,
      isLoggingRequestOriginsEnabled,
      isImageDecoderEnabledForBitmaps);
}

这里就完成了Glide的构建。

然后我们回到最开始的getRetriever(activity).get(activity),看看这个函数里面都干了些什么:

java 复制代码
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
//首先判断当前是否在子线程中
  if (Util.isOnBackgroundThread()) {
//在子线程中 就通过Application级别的上下文加载
    return get(activity.getApplicationContext());
  } else {
//检查Activity是否已经销毁
    assertNotDestroyed(activity);
//拿到当前activity的fragmentmanager
    FragmentManager fm = activity.getSupportFragmentManager();
//生成一个fragment 然后绑定一个请求管理类RequestManager
    return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
  }
}

看到这里,我们就应该意识到一个问题,如果我们在子线程中去调用Glide的话,就会使用应用级别的上下文去加载图片,这样大量使用,可能会导致内存泄漏。

然后在主线程中使用,就是Glide的精髓之一了,加载一个透明fragment来感应当前页面的生命周期的变化。

接着看看supportFragmentGet是怎么实现的:

java 复制代码
@NonNull
private RequestManager supportFragmentGet(
    @NonNull Context context,
    @NonNull FragmentManager fm,
    @Nullable Fragment parentHint,
    boolean isParentVisible) {
//在当前的 Acitivty 添加一个 Fragment 用于管理请求的生命周期
  SupportRequestManagerFragment current =
      getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
//拿到当前请求的管理类
  RequestManager requestManager = current.getRequestManager();
//如果为空 就创建一个
  if (requestManager == null) {
    // TODO(b/27524013): Factor out this Glide.get() call.
    Glide glide = Glide.get(context);
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    current.setRequestManager(requestManager);
  }
  return requestManager;
}

这里就是添加一个fragment管理生命周期。然后返回一个RequestManager对象。

接下来再具体看看getSupportRequestManagerFragment是怎么添加的:

java 复制代码
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
    @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
//通过tag拿到fragment实例 避免重复
  SupportRequestManagerFragment current =
      (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
//没有实例的话 就去缓存找
  if (current == null) {
    current = pendingSupportRequestManagerFragments.get(fm);
//缓存也没有 就创建一个
    if (current == null) {
      current = new SupportRequestManagerFragment();
      current.setParentFragmentHint(parentHint);
      if (isParentVisible) {
        current.getGlideLifecycle().onStart();
      }
      pendingSupportRequestManagerFragments.put(fm, current);
      fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
      handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
    }
  }
  return current;
}

这里主要是拿到fragment实例。

从上面我们可以看出Glide主要是做了一些初始化的工作,缓存,线程池,复用池的构建等等。

然后绑定了一个fragment来管理生命周期

with的源码差不多就是这些,可能比较繁琐,但是不像rxjava那样绕来绕去的,主线还是比较清晰的。

五,模拟Glide生命周期管理

首先创建一个接口,监听生命周期回调:

java 复制代码
public interface LifecycleListener {
    
    void onCreate();


    void onStart();


    void onStop();


    void onDestroy();

}

然后创建一个用来管理生命周期监听的接口:

java 复制代码
public interface Lifecycle {

    void addListener(@NonNull LifecycleListener listener);

    void removeListener(@NonNull LifecycleListener listener);

}

通过上面的分析,我们知道Glide传入的上下文有应用级别的和非应用级别的。所以我们首先创建一个应用级别的Lifecycle:

java 复制代码
public class ApplicationLifecycle implements Lifecycle {

    @Override
    public void addListener(@NonNull LifecycleListener listener) {
        /**
         * APP启动的时候,执行onCreate
         */
        listener.onCreate();
    }

    @Override
    public void removeListener(@NonNull LifecycleListener listener) {
        
       //APP销毁的时候,啥也不用做了
    }
}

然后创建一个非应用级别的lifecycle:

java 复制代码
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.onCreate();
        } else {
            listener.onStop();  
        }
    }

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

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

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

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

创建一个具体的RequestManager 管理生命周期:

java 复制代码
public class RequestManager implements LifecycleListener {

    private Lifecycle lifecycle;

    public RequestManager(Lifecycle lifecycle, Context applicationContext) {
        this.lifecycle = lifecycle;
        this.lifecycle.addListener(this);
    }

    @Override
    public void onCreate() {
        Log.d(LOG.TAG, "yh-----onCreate");
    }

    @Override
    public void onStart() {
        Log.d(LOG.TAG, "yh-----onStart");
    }

    @Override
    public void onStop() {
        Log.d(LOG.TAG, "yh-----onStop");
    }

    @Override
    public void onDestroy() {
        Log.d(LOG.TAG, "yh-----onDestroy");
        this.lifecycle.removeListener(this);
    }
}

创建一个空白的fragment:

java 复制代码
public class RequestManagerFragment extends Fragment {

    
    private final ActivityFragmentLifecycle lifecycle;
    @Nullable
    private RequestManager requestManager;

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

    @VisibleForTesting
    @SuppressLint("ValidFragment")
    public RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
        this.lifecycle = lifecycle;
    }

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

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

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

    @Nullable
    public RequestManager getRequestManager() {
        return 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管理类:

java 复制代码
public class Glide {

    private static volatile Glide glide;

    @NonNull
    public static Glide get(@NonNull Context context) {
        if (glide == null) {
            synchronized (Glide.class) {
                if (glide == null) {
                    glide = new Glide();
                }
            }
        }
        return glide;
    }

    @NonNull
    public static RequestManager with(@NonNull Context context) {
        return new RequestManager(new ActivityFragmentLifecycle(),context);
    }

    @NonNull
    public static RequestManager withApplication(@NonNull Context context) {
        return new RequestManager(new ApplicationLifecycle(),context);
    }

}

使用也很简单:

java 复制代码
public class DemoActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Glide.with(this);
        Glide.withApplication(this.getApplicationContext());
    }
}

这样当DemoActivity创建时,会创建一个ActivityFragmentLifecycle,执行它的onStart方法,从而调用RequestManager的onStart方法,onDestory也是同样的道理。这样就实现了生命周期的检测。这里只是简单写下有助于理解Glide内部是怎么做的。

关于load和into以及缓存机制 改天再写。

相关推荐
林九生1 小时前
【Android】解决 ADB 中 SELinux 设置与 `Failed transaction (2147483646)` 错误
android·adb
归寻太乙2 小时前
C++初阶:模版的进阶使用
android·java·c++
IH_LZH2 小时前
OkHttp源码分析:分发器任务调配,拦截器责任链设计,连接池socket复用
android·java·okhttp·kotlin
i听音乐的猿2 小时前
Android HandlerThread、Looper、MessageQueue 源码分析
android
小手冰凉__2 小时前
Frida进行Android dex文件整体脱壳
android·安全
H1002 小时前
Android monitor.exe不支持jdk8以上
android
暮雪倾风4 小时前
【Android开发】安装Android Studio(2023.1.1)
android·ide·android studio
诸神缄默不语4 小时前
在Win11系统上安装Android Studio
android·ide·android studio
就爱学编程5 小时前
重生之我在异世界学编程之C语言:深入预处理篇(下)
android·java·c语言