Glide源码执行流程

文章详细介绍了Glide库中如何使用with()方法创建RequestManager,以及如何通过load()方法加载网络图片的过程。涉及到RequestManager的生命周期管理,包括通过SupportRequestManagerFragment与Activity生命周期同步,以及ModelLoader的创建和工厂模式的应用。
摘要由CSDN通过智能技术生成

阅读源码技巧:抽丝剥茧、点到为止。应该认准一个功能点,然后去分析这个功能点是如何实现的。但只要去追寻主体的实现逻辑即可,千万不要试图去搞懂每一行代码都是什么意思,那样很容易陷入思维黑洞当中,而且越陷越深。因为这些庞大的系统都不是一个人写出来的,每一行代码都想搞明白,就会感觉自己是在盲人摸象,永远也研究不透。如果只是去分析主体的实现逻辑,那么就比较明确的目的性,阅读源码会更加轻松,也更加有成效。

这篇主要是将以下代码搞明白是如何实现将一张网络图片展示到ImageView上面的,将Glide的一整套图片加载机制记得基本流程梳理:

Glide.with(this).load(url).into(imageView);

总体设计

1、with()

with()方法主要用于创建RequestManager,Glide是通过Activity/Fragment生命周期管理Request,流程图如下:

从with()方法入手,with方法传入的参数可以是context、Activity、Fragment或FragmentActivity,以FragmentActivity为例子:

public static RequestManager with(FragmentActivity activity) {
    RequestManagerRetriever retriever = RequestManagerRetriever.get();
    return retriever.get(activity);
}

获取了RequestManagerRetriever,并调用了其get方法:

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

判断是否在主线程中调用,如果是子线程中,则调用 get(activity.getApplicationContext()):

public RequestManager get(Context context) {
    if (context == null) {
        throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
        if (context instanceof FragmentActivity) {
            return get((FragmentActivity) context);
        } else if (context instanceof Activity) {
            return get((Activity) context);
        } else if (context instanceof ContextWrapper) {
            return get(((ContextWrapper) context).getBaseContext());
        }
    }

    return getApplicationManager(context);
}

很明显传入的context是ApplicationContext,所以会调用getApplicationManager(context):

private RequestManager getApplicationManager(Context context) {
    // Either an application context or we're on a background thread.
    if (applicationManager == null) {
        synchronized (this) {
            if (applicationManager == null) {
                // Normally pause/resume is taken care of by the fragment we add to the fragment or activity.
                // However, in this case since the manager attached to the application will not receive lifecycle
                // events, we must force the manager to start resumed using ApplicationLifecycle.
                applicationManager = new RequestManager(context.getApplicationContext(),
                        new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
            }
        }
    }

    return applicationManager;
}

创建了一个RequestManager,并将其返回,这里的ApplicationLifecycle很重要,后面会提到,再回到之前的get方法:

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

如果在主线程中调用get方法,则会通过获取传入activity的FragementManager,并将其传入到supportFragementGet(activity,fm)方法中:

RequestManager supportFragmentGet(Context context, FragmentManager fm) {
    SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
        requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
        current.setRequestManager(requestManager);
    }
    return requestManager;
}

首先是调用getSupportRequestManagerFragment方法获取一个SupportRequestManagerFragment,SupportRequestManagerFragment是一个无界面的Fragement类,起到把请求和Activity生命周期同步的作用:

SupportRequestManagerFragment getSupportRequestManagerFragment(final FragmentManager fm) {
    SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(


        FRAGMENT_TAG);
    if (current == null) {
        current = pendingSupportRequestManagerFragments.get(fm);
        if (current == null) {
            current = new SupportRequestManagerFragment();
            pendingSupportRequestManagerFragments.put(fm, current);
            fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
            handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
        }
    }
    return current;
}

可以看到getSupportRequestManagerFragment中,会先去判断传入的FragmentManager中是否已经绑定了这个SupportRequestManagerFragment,没有就将其创建并,并添加到FragmentManager中。

可以看到SupportRequestManagerFragment中生命周期的方法,都会同步调用lifecycle的相应方法:

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

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

而这个lifecycle就是ActivityFragmentLifecycle,它将用了观察者模式,可以发现addListener就是添加观察者,然后每一个生命周期方法,同步给 每一个listener:

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

    if (isDestroyed) {
        listener.onDestroy();
    } else if (isStarted) {
        listener.onStart();
    } else {
        listener.onStop();
    }
}

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

回到supportFragmentGet方法中:

RequestManager supportFragmentGet(Context context, FragmentManager fm) {
    SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
        requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
        current.setRequestManager(requestManager);
    }
    return requestManager;
}

接下来就是获取SupportRequestManagerFragment中的RequestManager中的RequestManager,判断其是否存在,不在则进行创建,然后和SupportRequestManagerFragment进行绑定,这里需要强调的是,构建RequestManager时,将SupportRequestManagerFragment的lifecycle传入,下面是RequestManager构造函数:

RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
        RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
    this.context = context.getApplicationContext();
    this.lifecycle = lifecycle;
    this.treeNode = treeNode;
    this.requestTracker = requestTracker;
    this.glide = Glide.get(context);
    this.optionsApplier = new OptionsApplier();

    ConnectivityMonitor connectivityMonitor = factory.build(context,
            new RequestManagerConnectivityListener(requestTracker));

    // If we're the application level request manager, we may be created on a background thread. In that case we
    // cannot risk synchronously pausing or resuming requests, so we hack around the issue by delaying adding
    // ourselves as a lifecycle listener by posting to the main thread. This should be entirely safe.
    if (Util.isOnBackgroundThread()) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                lifecycle.addListener(RequestManager.this);
            }
        });
    } else {
        lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);
}

可以发现,lifecycle.addListener方法,将RequestManager自身添加到lifecycle中,这里巧妙之处在于,SupportRequestManagerFragement的生命周期方法,都会同步通知lifecycle的所有Listener,所以SupportRequestManagerFragement的生命周期都可同步通知RequestManager。

上面还做了判断,如果这个RequestManager是application级别的,将其post到主线程,再调用lifecycle.addListener(RequestManager.this)方法,保证生命周期的同步效果。

总结:通过with()方法中的参数不同,调用RequestManagerRetriever的get方法,最终创建一个空的Fragement名为SupportRequestManagerFragment并绑定一个RequestManager。

2、load()

with()方法返回的是一个RequestManager,那么load()方法逻辑就是在RequestManager中。

load()调用处理流程图:

public DrawableTypeRequest<String> load(String string) {
    return (DrawableTypeRequest<String>) fromString().load(string);
}

会先调用fromString在调用load方法:

public DrawableTypeRequest<String> fromString() {
    return loadGeneric(String.class);
}
private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
    ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
    ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
            Glide.buildFileDescriptorModelLoader(modelClass, context);
    if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
        throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"
                + " which there is a registered ModelLoader, if you are using a custom model, you must first call"
                + " Glide#register with a ModelLoaderFactory for your custom model class");
    }

    return optionsApplier.apply(
            new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                    glide, requestTracker, lifecycle, optionsApplier));
}

loadGeneric方法中创建了两个ModeLoader,分别是streamModelLoader和fileDescriptorModelLoader,然后通过它们构造一个DrawableTypeRequest。

其实就是通过工厂模式创建相应类型的ModeLoader,以 Glide.buildStreamModelLoader为例:

public static <T> ModelLoader<T, InputStream> buildStreamModelLoader(Class<T> modelClass, Context context) {
    return buildModelLoader(modelClass, InputStream.class, context);
}

这里传递了InputStream.class:

public static <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass,
        Context context) {
     if (modelClass == null) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Unable to load null model, setting placeholder only");
        }
        return null;
    }
    return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
}

通过Glide.get(context).getLoaderFactory()获取GenericLoaderFactory()并调用buildModelLoader创建InputStream.class对应的ModelLoader:

public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
    ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
    if (result != null) {
        // We've already tried to create a model loader and can't with the currently registered set of factories,
        // but we can't use null to demonstrate that failure because model loaders that haven't been requested
        // yet will be null in the cache. To avoid this, we use a special signal model loader.
        if (NULL_MODEL_LOADER.equals(result)) {
            return null;
        } else {
            return result;
        }
    }

    final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
    if (factory != null) {
        result = factory.build(context, this);
        cacheModelLoader(modelClass, resourceClass, result);
    } else {
        // We can't generate a model loader for the given arguments with the currently registered set of factories.
        cacheNullLoader(modelClass, resourceClass);
    }
    return result;
}

getCachedLoader方法判断InputStream.class对应的ModelLoader是否已经创建过,也就是是否存在内存缓存中,有则返回。

然后调用了getFactory方法,根据InputStream.class,创建其对应的ModelLoaderFactory:

private <T, Y> ModelLoaderFactory<T, Y> getFactory(Class<T> modelClass, Class<Y> resourceClass) {
    Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
    ModelLoaderFactory/*T, Y*/ result = null;
    if (resourceToFactories != null) {
        result = resourceToFactories.get(resourceClass);
    }

    if (result == null) {
        for (Class<? super T> registeredModelClass : modelClassToResourceFactories.keySet()) {
            // This accounts for model subclasses, our map only works for exact matches. We should however still
            // match a subclass of a model with a factory for a super class of that model if if there isn't a
            // factory for that particular subclass. Uris are a great example of when this happens, most uris
            // are actually subclasses for Uri, but we'd generally rather load them all with the same factory rather
            // than trying to register for each subclass individually.
            if (registeredModelClass.isAssignableFrom(modelClass)) {
                Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> currentResourceToFactories =
                        modelClassToResourceFactories.get(registeredModelClass);
                if (currentResourceToFactories != null) {
                    result = currentResourceToFactories.get(resourceClass);
                    if (result != null) {
                        break;
                    }
                }
            }
        }
    }

    return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值