摘要:版本問題如何實(shí)現(xiàn)與生命周期的綁定如何實(shí)現(xiàn)緩存如何實(shí)現(xiàn)圖片壓縮如何實(shí)現(xiàn)與生命周期的綁定創(chuàng)建將其與傳入的生命周期綁定這樣做的好處是當(dāng)時(shí),也會(huì)做相應(yīng)操作,如停掉圖片加載綁定首先無論傳入的是什么,只要是在子線程中調(diào)用創(chuàng)建的與綁定,這樣創(chuàng)建的的生命周
版本4.9.0
問題Glide如何實(shí)現(xiàn)與生命周期的綁定?
Glide如何實(shí)現(xiàn)緩存?
Glide如何實(shí)現(xiàn)圖片壓縮?
Glide如何實(shí)現(xiàn)與生命周期的綁定?創(chuàng)建RequestManger,將其與with()傳入 Activity, Fragment的生命周期綁定,
這樣做的好處是當(dāng)Activity/Fragment stop/destroy時(shí),RequestManager也會(huì)做相應(yīng)操作,如停掉圖片加載
綁定Application Context
首先無論with()傳入的是什么,只要是在子線程中調(diào)用,創(chuàng)建的RequestManger與 Application Context綁定,這樣創(chuàng)建的RequestMangager的生命周期與
if (Util.isOnBackgroundThread()) { return get(fragment.getActivity().getApplicationContext()); } else { ... ... }
這樣做的目的是防止Activity,Fragment內(nèi)存泄漏
Activity與FramgentActivity
class RequestManagerFragment { ... ... private final ActivityFragmentLifecycle lifecycle; @Override public void onStart() { super.onStart(); lifecycle.onStart(); } @Override public void onStop() { super.onStop(); lifecycle.onStop(); } @Override public void onDestroy() { super.onDestroy(); lifecycle.onDestroy(); unregisterFragmentWithRoot(); } ... ... }
class ActivityFragmentLifecycle implements Lifecycle { @Override public void addListener(@NonNull 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(); } } void onStop() { isStarted = false; for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) { lifecycleListener.onStop(); } } void onDestroy() { isDestroyed = true; for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) { lifecycleListener.onDestroy(); } } }
RequestManagerFragment current = getRequestManagerFragment(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); }
RequestManagerFragment中創(chuàng)建了并對(duì)外提供ActivityFragmentLifecycle對(duì)象,
創(chuàng)建RequestManager時(shí),傳入ActivityFragmentLifecycle對(duì)象
RequestManager( Glide glide, Lifecycle lifecycle, RequestManagerTreeNode treeNode, RequestTracker requestTracker, ConnectivityMonitorFactory factory, Context context) { ... ... lifecycle.addListener(this); ... ... } @Override public synchronized void onStart() { resumeRequests(); targetTracker.onStart(); } @Override public synchronized void onStop() { pauseRequests(); targetTracker.onStop(); } @Override public synchronized void onDestroy() { targetTracker.onDestroy(); for (Target> target : targetTracker.getAll()) { clear(target); } targetTracker.clear(); requestTracker.clearRequests(); lifecycle.removeListener(this); lifecycle.removeListener(connectivityMonitor); mainHandler.removeCallbacks(addSelfToLifecycle); glide.unregisterRequestManager(this); }
這樣RequestManger.onStart(),onStop(),onDestroy()與Activity的生命周期通過Activity綁定的空Fragment實(shí)現(xiàn)了綁定
Fragment
與Activity的綁定方式類似,
FragmentManager fm = fragment.getChildFragmentManager();
將RequestManger.onStart(),onStop(),onDestroy()與Fragment的生命周期通過Fragment綁定的空Fragment實(shí)現(xiàn)的綁定
View
通過View可以獲取它所在的Activity 或 Fragment
Activity activity = findActivity(view.getContext()); @Nullable private Activity findActivity(@NonNull Context context) { if (context instanceof Activity) { return (Activity) context; } else if (context instanceof ContextWrapper) { return findActivity(((ContextWrapper) context).getBaseContext()); } else { return null; } } @Nullable private Fragment findSupportFragment(@NonNull View target, @NonNull FragmentActivity activity) { tempViewToSupportFragment.clear(); findAllSupportFragmentsWithViews( activity.getSupportFragmentManager().getFragments(), tempViewToSupportFragment); Fragment result = null; View activityRoot = activity.findViewById(android.R.id.content); View current = target; while (!current.equals(activityRoot)) { result = tempViewToSupportFragment.get(current); if (result != null) { break; } if (current.getParent() instanceof View) { current = (View) current.getParent(); } else { break; } } tempViewToSupportFragment.clear(); return result; }
Context
通過Context獲取Activity or FragmentActivity or Application Context
if (context == null) { throw new IllegalArgumentException("You cannot start a load on a nullContext"); } 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);Glide如何實(shí)現(xiàn)緩存?
提供了兩個(gè)內(nèi)存緩存,分別存儲(chǔ)強(qiáng)弱引用
弱引用的緩存: 存放正在使用的
強(qiáng)引用的緩存: 存放沒有使用的
MapactiveEngineResources//在 private final Map cache = new LinkedHashMap<>(100, 0.75f, true);//在LruCache類中
查找內(nèi)存緩存,
1.先從弱引用的緩存查, 2.沒有再從強(qiáng)引用的緩存查,查到后從強(qiáng)引用緩存中移除,加入到弱引用的緩存
Engine.load()方法
EngineResource> active = loadFromActiveResources(key, isMemoryCacheable); if (active != null) { cb.onResourceReady(active, DataSource.MEMORY_CACHE); if (VERBOSE_IS_LOGGABLE) { logWithTimeAndKey("Loaded resource from active resources", startTime, key); } return null; } EngineResource> cached = loadFromCache(key, isMemoryCacheable);
Engine.loadFromCache()方法
private EngineResource> loadFromCache(Key key, boolean isMemoryCacheable) { if (!isMemoryCacheable) { return null; } EngineResource> cached = getEngineResourceFromCache(key); // if (cached != null) { cached.acquire(); activeResources.activate(key, cached); } return cached; } private EngineResource> getEngineResourceFromCache(Key key) { Resource> cached = cache.remove(key); final EngineResource> result; if (cached == null) { result = null; } else if (cached instanceof EngineResource) { // Save an object allocation if we"ve cached an EngineResource (the typical case). result = (EngineResource>) cached; } else { result = new EngineResource<>(cached, true /*isMemoryCacheable*/, true /*isRecyclable*/); } return result; }Glide如何實(shí)現(xiàn)圖片壓縮?
Glide實(shí)現(xiàn)的等比壓縮,保持原圖長寬比例,主要是通過原圖寬高和預(yù)設(shè)的寬高設(shè)置 BitmapFactory.Options.inSampleSize
float widthPercentage = requestedWidth / (float) sourceWidth; float heightPercentage = requestedHeight / (float) sourceHeight; exactScaleFactor = Math.min(widthPercentage, heightPercentage); int outWidth = round(exactScaleFactor * sourceWidth); int outHeight = round(exactScaleFactor * sourceHeight); int widthScaleFactor = sourceWidth / outWidth; int heightScaleFactor = sourceHeight / outHeight; int scaleFactor = rounding == SampleSizeRounding.MEMORY ? Math.max(widthScaleFactor, heightScaleFactor) : Math.min(widthScaleFactor, heightScaleFactor); int powerOfTwoSampleSize; // BitmapFactory does not support downsampling wbmp files on platforms <= M. See b/27305903. if (Build.VERSION.SDK_INT <= 23 && NO_DOWNSAMPLE_PRE_N_MIME_TYPES.contains(options.outMimeType)) { powerOfTwoSampleSize = 1; } else { powerOfTwoSampleSize = Math.max(1, Integer.highestOneBit(scaleFactor)); if (rounding == SampleSizeRounding.MEMORY && powerOfTwoSampleSize < (1.f / exactScaleFactor)) { powerOfTwoSampleSize = powerOfTwoSampleSize << 1; } } options.inSampleSize = powerOfTwoSampleSize;
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/73718.html
摘要:從這段代碼入手分析分析從這段代碼可以看出無論傳入的是還是或者干脆傳入或都會(huì)調(diào)用這個(gè)方法而這個(gè)方法生成兩個(gè)對(duì)象對(duì)象,并把它加到上對(duì)象這兩個(gè)對(duì)象擁有共同的對(duì)象對(duì)象,當(dāng)系統(tǒng)調(diào)用的生命周期,的生命周期隨之被調(diào)用來處理列表,將的生命周期與的生命周期聯(lián) 從這段代碼入手分析Glide Glide.with(context) .load(url) .placehol...
Glide取消圖片加載1.在任務(wù)剛開始時(shí);2.在EngineJob中,Future.cancel(true)3.在加載完成,但沒有加載到控件;RequestManager.java: public void pauseRequests() { Util.assertMainThread(); requestTracker.pauseRequests(); ...