源碼分析--Glide源碼 加載圖片 一 with與load

寫在前面

有一段時(shí)間沒有寫過博客了,中間了看了一些雜七雜八的東西,也過了一部分的面試題,順帶提一句面試題我都是在鴻洋的https://www.wanandroid.com/ 看的,里面分類很多也比較的全,建議收藏

打開百度搜索Gilde源碼會(huì)出現(xiàn)幾百萬的搜索結(jié)果,但是我為什么還要再寫這篇博客呢?

第一 可以給后來的人指路。第二 可以都在哪怕是復(fù)述的時(shí)候,提高自己表達(dá)溝通的能力,第三 在加強(qiáng)自己的理解,哪怕是后面忘了也可以通過這篇文章在快速的回想起代碼中的一切。

這三點(diǎn)來說 第一點(diǎn)反而是最小的一點(diǎn),重點(diǎn)在第二第三點(diǎn)。

對(duì)于Glide來講,代碼中用了大量的復(fù)用,轉(zhuǎn)型等,所以建議大家在看源碼時(shí)把自己看的代碼用云筆記保存起來,方便回溯


對(duì)于Glide源碼來講,這應(yīng)該也是一個(gè)新坑,由于篇幅肯定不會(huì)一次性全部講完,具體要分幾節(jié)可能還要看具體的情況


對(duì)于第一篇Glide源碼解析來講,最主要的還是走一遍完整的網(wǎng)絡(luò)請(qǐng)求的流程,選用Glide版本是3.7.0。因?yàn)檫@個(gè)是我第一次接觸Glide使用的版本,之前也看過一部分的代碼,為了省事,我還是選用了這個(gè)版本

首先我們現(xiàn)在看一下Glide的使用方法

String s = "https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=1066881363,1963636720&fm=173&app=25&f=JPEG?w=639&h=426&s=BF104C810E535FD624B4D89F0300C080";
Glide.with(MainActivity.this).load(s).into(imageView);

這個(gè)是最基本的使用方法,分為with,load,into三個(gè)步驟,我們一個(gè)個(gè)看過來

with

    public static RequestManager with(FragmentActivity activity) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(activity);
    }
 
    public RequestManager get(FragmentActivity activity) {
        if (Util.isOnBackgroundThread()) {
        //如果不在主線程復(fù)用get(context)的方法
            return get(activity.getApplicationContext());
        } else {
            assertNotDestroyed(activity);
            //獲取出一個(gè)FragmentManager來監(jiān)聽Activity的生命周期
            FragmentManager fm = activity.getSupportFragmentManager();
            return supportFragmentGet(activity, fm);
        }
    }
    
    //關(guān)鍵代碼
    RequestManager supportFragmentGet(Context context, FragmentManager fm) {
        //需要關(guān)注這個(gè)方法
        SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
            requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }

通過fm獲取出來一個(gè)SupportRequestManagerFragment對(duì)象,看一下這個(gè)是怎么獲取的

    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;
    }

這里的邏輯比較清晰了,通過fm創(chuàng)建了一個(gè)空白的Fragment,并溝通過接口的方式監(jiān)聽了這個(gè)Fragment的生命周期,具體的實(shí)現(xiàn)可以通過看SupportRequestManagerFragment構(gòu)造器得知。
繼續(xù)看下去

    RequestManager supportFragmentGet(Context context, FragmentManager fm) {
        //需要關(guān)注這個(gè)方法
        SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
            requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }

初始話了一個(gè)RequestManager對(duì)象并返回,我們看一下RequestManager的構(gòu)造器

public RequestManager(Context context, Lifecycle lifecycle, RequestManagerTreeNode treeNode) {
        this(context, lifecycle, treeNode, new RequestTracker(), new ConnectivityMonitorFactory());
    }

    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;
        //初始話了Glide
        this.glide = Glide.get(context);
        this.optionsApplier = new OptionsApplier();

        ConnectivityMonitor connectivityMonitor = factory.build(context,
                new RequestManagerConnectivityListener(requestTracker));
        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);
    }

可以看到這里面做了部分?jǐn)?shù)據(jù)的初始話,其中比較重要的就是Glide的初始話,我們可以看一下Glide的初始話方法

 public static Glide get(Context context) {
        if (glide == null) {
            synchronized (Glide.class) {
                if (glide == null) {
                    Context applicationContext = context.getApplicationContext();
                    List<GlideModule> modules = new ManifestParser(applicationContext).parse();

                    GlideBuilder builder = new GlideBuilder(applicationContext);
                    for (GlideModule module : modules) {
                        module.applyOptions(applicationContext, builder);
                    }
                    glide = builder.createGlide();
                    for (GlideModule module : modules) {
                        module.registerComponents(applicationContext, glide);
                    }
                }
            }
        }

        return glide;
    }

        Glide createGlide() {
        if (sourceService == null) {
            final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());
            sourceService = new FifoPriorityThreadPoolExecutor(cores);
        }
        if (diskCacheService == null) {
            diskCacheService = new FifoPriorityThreadPoolExecutor(1);
        }

        MemorySizeCalculator calculator = new MemorySizeCalculator(context);
        if (bitmapPool == null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                int size = calculator.getBitmapPoolSize();
                bitmapPool = new LruBitmapPool(size);
            } else {
                bitmapPool = new BitmapPoolAdapter();
            }
        }

        if (memoryCache == null) {
            memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());
        }

        if (diskCacheFactory == null) {
            diskCacheFactory = new InternalCacheDiskCacheFactory(context);
        }

        if (engine == null) {
            engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
        }

        if (decodeFormat == null) {
            decodeFormat = DecodeFormat.DEFAULT;
        }

        return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
    }

     Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
        this.engine = engine;
        this.bitmapPool = bitmapPool;
        this.memoryCache = memoryCache;
        this.decodeFormat = decodeFormat;
        loaderFactory = new GenericLoaderFactory(context);
        mainHandler = new Handler(Looper.getMainLooper());
        bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);

        dataLoadProviderRegistry = new DataLoadProviderRegistry();

        StreamBitmapDataLoadProvider streamBitmapLoadProvider =
                new StreamBitmapDataLoadProvider(bitmapPool, decodeFormat);
        dataLoadProviderRegistry.register(InputStream.class, Bitmap.class, streamBitmapLoadProvider);

        FileDescriptorBitmapDataLoadProvider fileDescriptorLoadProvider =
                new FileDescriptorBitmapDataLoadProvider(bitmapPool, decodeFormat);
        dataLoadProviderRegistry.register(ParcelFileDescriptor.class, Bitmap.class, fileDescriptorLoadProvider);

        ImageVideoDataLoadProvider imageVideoDataLoadProvider =
                new ImageVideoDataLoadProvider(streamBitmapLoadProvider, fileDescriptorLoadProvider);
        dataLoadProviderRegistry.register(ImageVideoWrapper.class, Bitmap.class, imageVideoDataLoadProvider);

        GifDrawableLoadProvider gifDrawableLoadProvider =
                new GifDrawableLoadProvider(context, bitmapPool);
        dataLoadProviderRegistry.register(InputStream.class, GifDrawable.class, gifDrawableLoadProvider);

        dataLoadProviderRegistry.register(ImageVideoWrapper.class, GifBitmapWrapper.class,
                new ImageVideoGifDrawableLoadProvider(imageVideoDataLoadProvider, gifDrawableLoadProvider, bitmapPool));

        dataLoadProviderRegistry.register(InputStream.class, File.class, new StreamFileDataLoadProvider());

        register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
        register(File.class, InputStream.class, new StreamFileLoader.Factory());
        register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
        register(int.class, InputStream.class, new StreamResourceLoader.Factory());
        register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
        register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
        register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
        register(String.class, InputStream.class, new StreamStringLoader.Factory());
        register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
        register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
        register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
        register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
        register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());

        transcoderRegistry.register(Bitmap.class, GlideBitmapDrawable.class,
                new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool));
        transcoderRegistry.register(GifBitmapWrapper.class, GlideDrawable.class,
                new GifBitmapWrapperDrawableTranscoder(
                        new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));

        bitmapCenterCrop = new CenterCrop(bitmapPool);
        drawableCenterCrop = new GifBitmapWrapperTransformation(bitmapPool, bitmapCenterCrop);

        bitmapFitCenter = new FitCenter(bitmapPool);
        drawableFitCenter = new GifBitmapWrapperTransformation(bitmapPool, bitmapFitCenter);
    }

這里面做了很多東西的初始話,包括圖片三級(jí)緩存中的disk緩存和內(nèi)存緩存,還有注冊(cè)了一部分的方法,這里先不展開,我們只需要了解這些東西即可。
到這里基本上,第一個(gè)with方法就講完了,總結(jié)一下with干的內(nèi)容:
1.獲取了傳入Activity的fragmentManager,并且創(chuàng)建了一個(gè)空白的fragment用于監(jiān)聽Activity的生命周期,并最終封裝了一個(gè)requestManager
2.初始話了大量的參數(shù),其中包括了Glide本身,disk緩存和內(nèi)存緩存等。

load

先看一下load的用法

load("https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=1066881363,1963636720&fm=173&app=25&f=JPEG?w=639&h=426&s=BF104C810E535FD624B4D89F0300C080")

傳入的類型是String,看一下這個(gè)代碼的具體實(shí)現(xiàn)

 public DrawableTypeRequest<File> load(File file) {
        return (DrawableTypeRequest<File>) fromFile().load(file);
    }

 public DrawableTypeRequest<Uri> loadFromMediaStore(Uri uri) {
        return (DrawableTypeRequest<Uri>) fromMediaStore().load(uri);
    }
       public DrawableTypeRequest<Integer> load(Integer resourceId) {
        return (DrawableTypeRequest<Integer>) fromResource().load(resourceId);
    }
    public DrawableTypeRequest<URL> load(URL url) {
        return (DrawableTypeRequest<URL>) fromUrl().load(url);
    }
        public DrawableTypeRequest<String> load(String string) {
        return (DrawableTypeRequest<String>) fromString().load(string);
    }

這個(gè)方法有多個(gè)重載,對(duì)于傳入String的方法的具體實(shí)現(xiàn),主要關(guān)注fromString()這個(gè)方法

   public DrawableTypeRequest<String> fromString() {
        return loadGeneric(String.class);
    }
    
    private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
        //獲取到相應(yīng)的加載器
        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));
    }

這里最后return的值我們就把他看成new DrawableTypeRequest即可,這里完成大量的數(shù)據(jù)構(gòu)建,創(chuàng)建出來的兩個(gè)ModelLoader這里先不講,具體話會(huì)跟前一步的Glide的構(gòu)造器里面的register方法有關(guān),具體返回的值是HttpUrlGlideUrlLoader。接下來看一下DrawableTypeRequest的構(gòu)造方法

 DrawableTypeRequest(Class<ModelType> modelClass, ModelLoader<ModelType, InputStream> streamModelLoader,
            ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader, Context context, Glide glide,
            RequestTracker requestTracker, Lifecycle lifecycle, RequestManager.OptionsApplier optionsApplier) {
        super(context, modelClass,
                buildProvider(glide, streamModelLoader, fileDescriptorModelLoader, GifBitmapWrapper.class,
                        GlideDrawable.class, null),
                glide, requestTracker, lifecycle);
        this.streamModelLoader = streamModelLoader;
        this.fileDescriptorModelLoader = fileDescriptorModelLoader;
        this.optionsApplier = optionsApplier;
    }

關(guān)注一下buildProvider方法

private static <A, Z, R> FixedLoadProvider<A, ImageVideoWrapper, Z, R> buildProvider(Glide glide,
            ModelLoader<A, InputStream> streamModelLoader,
            ModelLoader<A, ParcelFileDescriptor> fileDescriptorModelLoader, Class<Z> resourceClass,
            Class<R> transcodedClass,
            ResourceTranscoder<Z, R> transcoder) {
        if (streamModelLoader == null && fileDescriptorModelLoader == null) {
            return null;
        }

        if (transcoder == null) {
            transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
        }
        DataLoadProvider<ImageVideoWrapper, Z> dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class,
                resourceClass);
        ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,
                fileDescriptorModelLoader);
        return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
    }

返回了一個(gè)FixedLoadProvider對(duì)象,這個(gè)對(duì)象在后面會(huì)用到記錄一下。

由于篇幅,暫時(shí)先講到這里,總結(jié)一下,with和load主要就是對(duì)Glide的初始化參數(shù)的,另外with會(huì)對(duì)當(dāng)前頁面創(chuàng)建一個(gè)FragmentManager,再用這個(gè)fm創(chuàng)建一個(gè)空的fragment來進(jìn)行對(duì)于這個(gè)頁面的更新,另外with方法還對(duì)Glide進(jìn)行初始化,并注冊(cè)了相應(yīng)的moderLoader。而load主要根據(jù)傳入的參數(shù)決定了對(duì)應(yīng)的moderLoader。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容