Glide生命周期管理
1.Glide特點(diǎn)
- 使用簡單
- 可配置度高假勿,自適應(yīng)程度高
- 支持常見圖片格式(jpg、png态鳖、gif转培、webp)
- 支持多種數(shù)據(jù)源(網(wǎng)絡(luò)、本地浆竭、資源浸须、Assets等)
- 高效緩存策略(支持Memory和Disk圖片緩存惨寿,默認(rèn)Bitmap格式采用RGB_565內(nèi)存小)
- 生命周期集成(根據(jù)Activity/Fragment生命周期自動(dòng)管理請求)
- 高效處理Bitmap(使用BitmapPool復(fù)用Bitmap删窒,主動(dòng)調(diào)用recycle回收需要回收的Bitmap)
2.Glide使用攻略
Glide.with(this)
// .asBitmap()//只允許加載靜態(tài)圖片裂垦,若傳入gif圖會(huì)展示第一幀(要在load之前)
// .asGif()//指定gif格式(要在load之前)
// .asDrawable()//指定drawable格式(要在load之前)
.load(imageUrl)//被加載圖像的url地址
.placeholder(R.drawable.ic_placeholder)//占位圖片
.error(R.drawable.ic_error)//錯(cuò)誤圖片
.transition(GenericTransitionOptions.with(R.anim.zoom_in))//圖片動(dòng)畫
.override(800,800)//設(shè)置加載尺寸
.skipMemoryCache(true)//禁用內(nèi)存緩存功能
.diskCacheStrategy(DiskCacheStrategy.NONE)//不緩存任何內(nèi)容
// .diskCacheStrategy(DiskCacheStrategy.DATA)//只緩存原始圖片
// .diskCacheStrategy(DiskCacheStrategy.RESOURCE)//只緩存轉(zhuǎn)換后的圖片
// .diskCacheStrategy(DiskCacheStrategy.ALL)//緩存所有
// .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)//Glide根據(jù)圖片資源智能地選擇使用哪一種緩存策略(默認(rèn))
.listener(new RequestListener<Drawable>() {//監(jiān)聽圖片加載狀態(tài)
//圖片加載完成
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
//圖片加載失敗
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(imageView);//圖片最終要展示的地方
3.Glide生命周期原理分析
Glide.with(this)
with方法可以接受Context,Activity肌索,F(xiàn)ragmentActivity蕉拢,F(xiàn)ragment和View不同的類型。
private static volatile Glide glide;
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
雙重檢測單例模式(DCL)保證Glide對象的唯一性驶社,get方法里面初始化了Glide企量,通過建造者模式創(chuàng)建了一個(gè)GlideBuilder對象(資源請求線程池,本地緩存加載線程池亡电,動(dòng)畫線程池届巩,內(nèi)存緩存器,磁盤緩存工具等等)份乒。
構(gòu)造完RequestManagerRetriever通過get返回一個(gè) RequestManager(以Activity為例)
//通過Activity拿到RequestManager
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
//如果是子線程就用Application級別的context恕汇,也就是不進(jìn)行生命周期管理
return get(activity.getApplicationContext());
} else {
//檢查Activity是否銷毀
assertNotDestroyed(activity)
//拿到當(dāng)前Activity的FragmentManager
android.app.FragmentManager fm = activity.getFragmentManager();
//生成一個(gè)Fragment去綁定一個(gè)請求管理RequestManager
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
如果當(dāng)前線程是子線程,則不需要對Glide生命周期進(jìn)行管理或辖,否則通過fragmentGet函數(shù)創(chuàng)建一個(gè)fragment:
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//①在當(dāng)前Activity添加一個(gè)Fragment用于管理請求的生命周期
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
//獲取RequestManager
RequestManager requestManager = current.getRequestManager();
//如果不存在RequestManager瘾英,則創(chuàng)建
if (requestManager == null) {
Glide glide = Glide.get(context);
//②構(gòu)建RequestManager
//current.getGlideLifecycle()就是ActivityFragmentLifecycle,也就是構(gòu)建RequestManager時(shí)會(huì)傳入fragment中的ActivityFragmentLifecycle
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
//將構(gòu)建出來的RequestManager綁定到fragment中
current.setRequestManager(requestManager);
}
//返回當(dāng)前請求的管理者
return requestManager;
}
①Fragment與Activity的綁定—>getRequestManagerFragment:
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//通過TAG拿到已經(jīng)實(shí)例化過的fragment(也就是同一個(gè)Activity Glide.with多次颂暇,沒必要?jiǎng)?chuàng)建多個(gè)fragment)
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//如果當(dāng)前Activity中沒有拿到管理生命周期的fragment缺谴,那就從緩存取
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
//如果緩存也沒有,直接new一個(gè)
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
//執(zhí)行請求
current.getGlideLifecycle().onStart();
}
//添加到Map緩存中(防止fragment重復(fù)創(chuàng)建)
pendingRequestManagerFragments.put(fm, current);
//將fragment綁定到activity
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//添加后發(fā)送清理緩存
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
②構(gòu)建RequestManager并設(shè)置監(jiān)聽
//此工廠就是為了構(gòu)建出 RequestManager對象
private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() {
@NonNull
@Override
public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) {
//實(shí)例化一個(gè)RequestManager
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};
public class RequestManager implements LifecycleListener,
ModelTypes<RequestBuilder<Drawable>> {
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
//添加生命周期監(jiān)聽
if (Util.isOnBackgroundThread()) {
//子線程通過handler將當(dāng)前對象注冊到ActivityFragmentLifecycle
mainHandler.post(addSelfToLifecycle);
} else {
//將當(dāng)前對象注冊到ActivityFragmentLifecycle
lifecycle.addListener(this);
}
//添加網(wǎng)絡(luò)變化的監(jiān)聽
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
//...
//RequestManager實(shí)現(xiàn)了fragment生命周期回調(diào)
@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);
}
}
構(gòu)建RequestManager的時(shí)候?qū)equestManager的生命周期與Fragment關(guān)聯(lián)起來了耳鸯。
Fragment是依附在Activity湿蛔,所以Activity的生命周期在Fragment中都有,接著我們來看下RequestManagerFragment:
public class RequestManagerFragment extends Fragment {
//生命周期的關(guān)鍵就在ActivityFragmentLifecycle
private final ActivityFragmentLifecycle lifecycle;
public RequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = 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();
}
//...
}
生命周期的關(guān)鍵就在lifecycle县爬,F(xiàn)ragment生命周期變化時(shí)會(huì)主動(dòng)通知lifecycle執(zhí)行相應(yīng)方法阳啥。
接著看下ActivityFragmentLifecycle:
class ActivityFragmentLifecycle implements Lifecycle {
//在Fragment生命周期變化時(shí)會(huì)通知所有的它的Listener
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.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
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();
}
}
}
這個(gè)ActivityFragmentLifecycle持有一個(gè)lifecycleListeners,在Fragment生命周期變化時(shí)會(huì)通知所有的它的Listener财喳。
4.Glide生命周期回調(diào)流程總結(jié)
??Glide.with(this)綁定了Activity的生命周期察迟。在Activity內(nèi)新建了一個(gè)無UI的Fragment,這個(gè)Fragment持有一個(gè)Lifecycle耳高,通過Lifecycle在Fragment關(guān)鍵生命周期通知RequestManager進(jìn)行相關(guān)從操作扎瓶。在生命周期onStart時(shí)繼續(xù)加載,onStop時(shí)暫停加載泌枪,onDestory時(shí)停止加載任務(wù)和清除操作栗弟。
Glide為什么對Fragment做緩存?
//添加到Map緩存中(防止fragment重復(fù)創(chuàng)建)
pendingRequestManagerFragments.put(fm, current);
//將fragment綁定到activity
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//添加后發(fā)送清理緩存的消息
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
一個(gè)場景:通過Glide加載兩張圖片并設(shè)置到兩個(gè)ImageView上工闺。
Glide.with(this).load(imageUrl1).into(imageView1);//msg1
Glide.with(this).load(imageUrl2).into(imageView2);//msg2
??執(zhí)行到getRequestManagerFragment這個(gè)方法時(shí)乍赫,會(huì)通過開啟事務(wù)的方式綁定fragment到activity,綁定操作最終是通過主線程的handler發(fā)送消息處理的陆蟆,Handler中的消息時(shí)按照順序執(zhí)行的雷厂。如果不把msg1構(gòu)建的RequestManagerFragment放到pendingRequestManagerFragments中,那么在執(zhí)行msg2的時(shí)候會(huì)重新創(chuàng)建一個(gè)重復(fù)的fragment并add叠殷。最后發(fā)消息清理緩存(避免內(nèi)存泄漏和減少內(nèi)存壓力)改鲫,因?yàn)橄⑹前凑枕樞驁?zhí)行的,執(zhí)行清理緩存的時(shí)候msg1和msg2已經(jīng)執(zhí)行完畢林束。
Glide如何監(jiān)聽網(wǎng)絡(luò)變化像棘?
在構(gòu)建RequestManager的時(shí)候通過lifecycle.addListener(connectivityMonitor);
添加網(wǎng)絡(luò)變化的監(jiān)聽 ,F(xiàn)ragment生命周期的變化會(huì)通知到默認(rèn)實(shí)現(xiàn)類DefaultConnectivityMonitor中對應(yīng)的方法壶冒。在onStart中registerReceiver(注冊監(jiān)聽手機(jī)網(wǎng)絡(luò)變化的廣播)缕题, 在onStop中unregisterReceiver。有網(wǎng)絡(luò)重連后重啟請求胖腾。
final class DefaultConnectivityMonitor implements ConnectivityMonitor {
private static final String TAG = "ConnectivityMonitor";
private final Context context;
@SuppressWarnings("WeakerAccess") @Synthetic final ConnectivityListener listener;
@SuppressWarnings("WeakerAccess") @Synthetic boolean isConnected;
private boolean isRegistered;
private final BroadcastReceiver connectivityReceiver = new BroadcastReceiver() {
@Override
public void onReceive(@NonNull Context context, Intent intent) {
boolean wasConnected = isConnected;
//判斷網(wǎng)絡(luò)狀態(tài)
isConnected = isConnected(context);
if (wasConnected != isConnected) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "connectivity changed, isConnected: " + isConnected);
}
listener.onConnectivityChanged(isConnected);
}
}
};
DefaultConnectivityMonitor(@NonNull Context context, @NonNull ConnectivityListener listener) {
this.context = context.getApplicationContext();
this.listener = listener;
}
private void register() {
if (isRegistered) {
return;
}
// Initialize isConnected.
isConnected = isConnected(context);
try {
// See #1405
context.registerReceiver(connectivityReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
isRegistered = true;
} catch (SecurityException e) {
// See #1417, registering the receiver can throw SecurityException.
if (Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Failed to register", e);
}
}
}
private void unregister() {
if (!isRegistered) {
return;
}
context.unregisterReceiver(connectivityReceiver);
isRegistered = false;
}
@SuppressWarnings("WeakerAccess")
@Synthetic
// Permissions are checked in the factory instead.
@SuppressLint("MissingPermission")
boolean isConnected(@NonNull Context context) {
ConnectivityManager connectivityManager =
Preconditions.checkNotNull(
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
NetworkInfo networkInfo;
try {
networkInfo = connectivityManager.getActiveNetworkInfo();
} catch (RuntimeException e) {
if (Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Failed to determine connectivity status when connectivity changed", e);
}
// Default to true;
return true;
}
return networkInfo != null && networkInfo.isConnected();
}
@Override
public void onStart() {
register();
}
@Override
public void onStop() {
unregister();
}
@Override
public void onDestroy() {
// Do nothing.
}
}
回調(diào)ConnectivityListener的onConnectivityChanged來處理請求
private class RequestManagerConnectivityListener
implements ConnectivityMonitor.ConnectivityListener {
@GuardedBy("RequestManager.this")
private final RequestTracker requestTracker;
RequestManagerConnectivityListener(@NonNull RequestTracker requestTracker) {
this.requestTracker = requestTracker;
}
@Override
public void onConnectivityChanged(boolean isConnected) {
if (isConnected) {
synchronized (RequestManager.this) {
//網(wǎng)絡(luò)重連后重啟請求
requestTracker.restartRequests();
}
}
}
}