Glideソース分析

6861 ワード

この記事はglide 3.7バージョンを分析しています


単純な使用

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


ソース実装の考え方

  • with() : Glide.with(activity)はRequestManagerクラスを返し、ここの先週の午後にactivityまたはfragmentを渡すことをお勧めします.glideはライフサイクルを監視し、ロードとリカバリを最適化します.RequestManagerはglideロードピクチャのライフサイクルとloadピクチャを処理するクラスです.
  • load():RequestManagerを使用してloadメソッドを呼び出し、最後にGenericRequestBuilderオブジェクトを返します.彼はoptionとintoを処理する実装ロジックです.(マルチステートプロパティ)asBitmapとasGifを呼び出していない場合は、デフォルトのDrawableRequestBuilderのインスタンスです.そうしないと、BitmapRequestBuilderとGifRequestBuilderです.このRequestBuilderは実は転送クラスで、本当に実装クラスはGenericRequestBuilderです.
  • into():私たちのすべてのパラメータをimageViewに表示します.
  • buildRequest():buildRequestは、GenericRequest obtain()を呼び出して、私たちが渡したすべてのパラメータに値を割り当て、パラメータが初期化され、Requestの実際のインスタンスがGenericRequestであることを返します.彼はtarget(imageView)にリソースをロードするクラス
  • です.
  • runRequest():buildパラメータ後にRequestTrackerクラスを呼び出すrunRequest()メソッドはGenericRequestを転送し、RequestTrackerはロード要求を追跡し、一時停止し、キャンセルし、再開始するなどの機能のクラスである.runRequest()ではGenericRequestのbegin()->onSizeReady()を呼び出し、Engineのload()を呼び出し、Engineはloadingリソースとキャッシュリソースを担当します.
  • load():方法は、まずloadFromCache()を使用してLruResourceCache(最近の最小使用アルゴリズム)を使用してメモリキャッシュを取得し、取得できない場合は弱い参照からloadFromActiveResourcesを使用してメモリキャッシュを取得します.いずれも取得できない場合はdikLruCacheを利用してディスクキャッシュを取得し、キャッシュオープンネットワークロードリソースを取得できません.
  • start():EngineJobのstart()メソッド.彼はEngineRunnableのrun()を実行してResourceリソースオブジェクトを取得します.
  • onResourceReady():EngineJobクラスのonResourceReadyという方法をコールバックします.targetのonResourceReadyメソッドがコールバックされます.

  • setResource():GlideDrawableImageView.setImageDrawable(resource);

  • glide符号化詳細分析
  • まずGlide.with(activity)
  • // 
    public RequestManager get(FragmentActivity activity) {
            if (Util.isOnBackgroundThread()) { 
                return get(activity.getApplicationContext());
            } else {
                assertNotDestroyed(activity);
                FragmentManager fm = activity.getSupportFragmentManager();
                return supportFragmentGet(activity, fm);// RequestManager
            }
        }
    
    
  • g e t S p o r t R equestManagerFragment:対応するactivityにfragmentを追加してライフサイクルを傍受し、tagとmapによってオブジェクトの多重化を行う.
  •   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;
        }
    
    
  • 上のnew個のRequestManagerオブジェクトは、構築方法でglideの初期化とライフサイクルの傍受処理
  • を行う.
        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);
        }
    
    
  • glideの一例では、GlideBuilderの作成およびcreateGlide()の方法は、glideパラメータを初期化したglideオブジェクト
  • を返す.
    public static Glide get(Context context) {
            if (glide == null) {
                synchronized (Glide.class) {
                    if (glide == null) {
                        Context applicationContext = context.getApplicationContext();
                        List 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;
        }
    
    
  • はそれぞれoptionがあるかどうかを判断し、ない場合はdefaultを設定する.
  •     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);//** **  11  Lru bitmap 
                } 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);
        }