Glide原始碼分析 一
阿新 • • 發佈:2019-02-01
從Glide入口開始
Glide最簡單的用法如下所示
Glide.with(context);
.load(url)
//硬碟儲存策略
.diskCacheStrategy(DiskCacheStrategy.ALL)
//是否啟用記憶體快取 預設為true
.skipMemoryCache(false)
.centerCrop()
.into(imageView);
with(context)
public static RequestManager with(Context context) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(context);
}
RequestManagerRetriever get(context)
依據傳入的context的型別, 進行相應的操作. context的型別主要分為FragmentActivity
, Activity
和ContextWrapper
, 當context是ContextWrapper
時, 呼叫get(Context context)
檢視其封裝的是哪一種Activity.
RequestManagerRetriever.java
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);
}
RequestManagerRetriever get(Activity) get(FragmentActivity)
RequestManagerRetriever.java
public RequestManager get(FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public RequestManager get(Activity activity) {
if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
return get(activity.getApplicationContext());
} else {
//判斷activity是否已經被銷燬, 如果銷燬丟擲異常
assertNotDestroyed(activity);
//獲取對應FragmenManager
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm);
}
}
這兩個方法差別不大, 主要是因為FragmentActivity
來自於support v4庫中, 和標準庫Activity獲取FragmentManager的方法以及返回的FragmentManager型別不太相同.
RequestManagerRetriever fragmentGet(Context, FramentManager)
RequestManagerRetriever.java
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
RequestManagerFragment getRequestManagerFragment(final android.app.FragmentManager fm) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
current = new RequestManagerFragment();
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
RequestManagerFragment current = getRequestManagerFragment(fm);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
current.setRequestManager(requestManager);
}
return requestManager;
}
這兩段程式碼的主要意義在於生成一個RequestManagerFragment
並沒有內容的但是繫結在制定的context上. 其實目的就是將該Fragment的生命週期繫結在該context上, 並在相應的方法呼叫時執行相應的操作.
RequestManagerFragment.java
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();
}
RequestManager
RequestManager implements LifecycleListener
//ActivityFragmentLifecycle 也實現了 LifecycleListener
@Override
public void onStart() {
// onStart might not be called because this object may be created after the fragment/activity's onStart method.
resumeRequests();
}
/**
* Lifecycle callback that unregisters for connectivity events (if the android.permission.ACCESS_NETWORK_STATE
* permission is present) and pauses in progress loads.
*/
@Override
public void onStop() {
pauseRequests();
}
/**
* Lifecycle callback that cancels all in progress requests and clears and recycles resources for all completed
* requests.
*/
@Override
public void onDestroy() {
requestTracker.clearRequests();
}
class ActivityFragmentLifecycle implements Lifecycle {
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
private boolean isStarted;
private boolean isDestroyed;
/**
* Adds the given listener to the list of listeners to be notified on each lifecycle event.
*
* <p>
* The latest lifecycle event will be called on the given listener synchronously in this method. If the
* activity or fragment is stopped, {@link LifecycleListener#onStop()}} will be called, and same for onStart and
* onDestroy.
* </p>
*
* <p>
* Note - {@link com.bumptech.glide.manager.LifecycleListener}s that are added more than once will have their
* lifecycle methods called more than once. It is the caller's responsibility to avoid adding listeners
* multiple times.
* </p>
*/
@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();
}
}
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
上述的程式碼總體的目的就是將RequestManager的生命週期和RequestManagerFragment繫結起來, 進而和Activity的生命週期繫結起來.
RequestManager
下面來看一下RequestManager的功能.
建構函式
RequestManager.java
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;
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.get(context)
該方法就是利用單例模式獲取一個Glide例項.
Glide.java
private static volatile 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;
}
GlideBuilder
利用GlideBuilder中的createGlide()方法生成了Glide, 在這個過程中完成了以下幾個任務:
- 初始化執行緒池
- 初始化bitmap池
- 初始化記憶體快取類
- 初始化內部磁碟快取類
- 初始化引擎類
- 設定預設的解碼格式
GlideBuilder.java
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);
}
//初始化bitmap池
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);
}
ManifestParser
ManifestParser.java
private static final String GLIDE_MODULE_VALUE = "GlideModule";
public List<GlideModule> parse() {
List<GlideModule> modules = new ArrayList<GlideModule>();
try {
//根據PackageName獲取metadata資訊
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
context.getPackageName(), PackageManager.GET_META_DATA);
//若有metadata資訊
if (appInfo.metaData != null) {
//遍歷metadata
for (String key : appInfo.metaData.keySet()) {
//將key和GLIDE_MODULE_VALUE相等的全部加入modules 之中
if (GLIDE_MODULE_VALUE.equals(appInfo.metaData.get(key))) {
modules.add(parseModule(key));
}
}
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("Unable to find metadata to parse GlideModules", e);
}
return modules;
}
//通過反射獲取GlideModule例項
private static GlideModule parseModule(String className) {
Class<?> clazz;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Unable to find GlideModule implementation", e);
}
Object module;
try {
module = clazz.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException("Unable to instantiate GlideModule implementation for " + clazz, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unable to instantiate GlideModule implementation for " + clazz, e);
}
if (!(module instanceof GlideModule)) {
throw new RuntimeException("Expected instanceof GlideModule, but found: " + module);
}
return (GlideModule) module;
}
通過反射的方式獲取在Manifest.xml中自定義的GlideModule物件, 獲得之後遍歷ArrayList, 對每一個GlideModuled呼叫相應的applyOptions()和registerComponents()方法.