Glide源码解读之绑定生命周期
程序员文章站
2022-03-10 15:36:37
今天有空,稍微解读了一下glide加载图片框架源码,glide源码比较多,除了弄清楚主流程,对我编程有帮助的,我都会记录下来。我这里不会一步一步详细解读源码,因为其他博客一大堆,我这里主要讲解一下原理;绑定生命周期,不用我们自己在onStart,onStop去调用,这种思想很好,所以,值得借鉴。主要实现原理是创建一个无UI的Fragment添加(绑定)到当前的Activity(或其他Fragment),通过重写Fragment的onStart和onStop方法,通知RequestManager任务改变...
今天有空,稍微解读了一下glide加载图片框架源码,glide源码比较多,除了弄清楚主流程,对我编程有帮助的,我都会记录下来。
我这里不会一步一步详细解读源码,因为其他博客一大堆,我这里主要讲解一下原理;
绑定生命周期,不用我们自己在onStart,onStop去调用,这种思想很好,所以,值得借鉴。
主要实现原理是创建一个无UI的Fragment添加(绑定)到当前的Activity(或其他Fragment),通过重写Fragment的onStart和onStop方法,通知RequestManager任务改变状态。
源码如下:
外观类:RequestManagerRetriever
package com.johan.glide;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import java.util.HashMap;
import java.util.Map;
public class RequestManagerRetriever implements Handler.Callback {
private static RequestManagerRetriever instance;
public static RequestManagerRetriever getInstance() {
if (instance == null) {
synchronized (RequestManagerRetriever.class) {
if (instance == null) {
instance = new RequestManagerRetriever();
}
}
}
return instance;
}
private Map<FragmentManager, RequestManagerFragment> tempMap;
private Handler handler;
public RequestManagerRetriever() {
tempMap = new HashMap<>();
handler = new Handler(Looper.getMainLooper(), this);
}
public RequestManager getRequestManager(FragmentActivity fragmentActivity) {
return getRequestManager(fragmentActivity.getSupportFragmentManager());
}
public RequestManager getRequestManager(Fragment fragment) {
return getRequestManager(fragment.getChildFragmentManager());
}
private RequestManager getRequestManager(FragmentManager fragmentManager) {
// 从 FragmentManager 通过 tag 获取 Fragment
RequestManagerFragment managerFragment = (RequestManagerFragment) fragmentManager.findFragmentByTag("com.johan.glide");
if (managerFragment == null) {
// 从临时缓存获取 Fragment
// 为什么要用到临时缓存呢?
// 比如连续两次调用 getRequestManager 方法
// 因为 fragmentManager.beginTransaction().add(managerFragment, "com.johan.glide").commitAllowingStateLoss(); 这句代码执行之后呢
// 创建的 Fragment 不会马上能被 fragmentManager.findFragmentByTag("com.johan.glide") 找到
// 防止重复添加到 FragmentManager
managerFragment = tempMap.get(fragmentManager);
if (managerFragment == null) {
// 创建
managerFragment = new RequestManagerFragment();
// 加入临时缓存
tempMap.put(fragmentManager, managerFragment);
// 添加到 FragmentManager
fragmentManager.beginTransaction().add(managerFragment, "com.johan.glide").commitAllowingStateLoss();
// 通知移除临时缓存
handler.obtainMessage(0, fragmentManager).sendToTarget();
}
}
// 先从 RequestManagerFragment 获取 RequestManager
RequestManager manager = managerFragment.getRequestManager();
if (manager == null) {
// 创建
manager = new RequestManager(managerFragment.getActivityLifeCycle());
// 设置
managerFragment.setRequestManager(manager);
}
return manager;
}
@Override
public boolean handleMessage(@NonNull Message message) {
// 移除临时缓存
tempMap.remove((FragmentManager) message.obj);
return true;
}
}
无 UI Fragment:RequestManagerFragment
package com.johan.glide;
import android.util.Log;
import androidx.fragment.app.Fragment;
public class RequestManagerFragment extends Fragment {
private ActivityLifeCycle activityLifeCycle;
private RequestManager requestManager;
public RequestManagerFragment() {
activityLifeCycle = new ActivityLifeCycle();
}
public ActivityLifeCycle getActivityLifeCycle() {
return activityLifeCycle;
}
public void setRequestManager(RequestManager requestManager) {
this.requestManager = requestManager;
}
public RequestManager getRequestManager() {
return requestManager;
}
@Override
public void onStart() {
super.onStart();
Log.e("glide", "RequestManagerFragment onStart --------- ");
// 生命周期回调
if (activityLifeCycle != null) {
activityLifeCycle.onStart();
}
}
@Override
public void onStop() {
super.onStop();
Log.e("glide", "RequestManagerFragment onStop --------- ");
// 生命周期回调
if (activityLifeCycle != null) {
activityLifeCycle.onStop();
}
}
}
生命周期监听接口:LifeCycleListener
public interface LifeCycleListener {
void onStart();
void onStop();
}
生命周期接听接口管理者:ActivityLifeCycle
package com.johan.glide;
import java.util.ArrayList;
import java.util.List;
public class ActivityLifeCycle implements LifeCycleListener {
private List<LifeCycleListener> lifeCycleListeners;
public ActivityLifeCycle() {
lifeCycleListeners = new ArrayList<>();
}
public void addLifeCycleListener(LifeCycleListener lifeCycleListener) {
lifeCycleListeners.add(lifeCycleListener);
}
public void removeLifeCycleListener(LifeCycleListener lifeCycleListener) {
lifeCycleListeners.remove(lifeCycleListener);
}
@Override
public void onStart() {
for (LifeCycleListener lifeCycleListener : lifeCycleListeners) {
lifeCycleListener.onStart();
}
}
@Override
public void onStop() {
for (LifeCycleListener lifeCycleListener : lifeCycleListeners) {
lifeCycleListener.onStop();
}
}
}
任务管理者:RequestManager
package com.johan.glide;
import android.util.Log;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class RequestManager implements LifeCycleListener {
private ExecutorService executorService;
private Future future;
public RequestManager(ActivityLifeCycle activityLifeCycle) {
executorService = Executors.newCachedThreadPool();
// 监听生命周期
activityLifeCycle.addLifeCycleListener(this);
}
/**
* 模拟耗时操作
*/
public void execute() {
future = executorService.submit(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 100; i++) {
Log.e("glide", this + " execute " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
@Override
public void onStart() {
Log.e("glide", "request start --------------");
}
@Override
public void onStop() {
Log.e("glide", "request stop --------------");
// 停止耗时操作
future.cancel(true);
executorService.shutdown();
}
}
我想可以用这种思想带到我们平常在Activity执行耗时操作中,这样我们的耗时操作就可以和我们的Activity生命周期一样,避免内存泄漏!!!
这里先做一个记录,继续分析glide源码!!!!!
本文地址:https://blog.csdn.net/JohanMan/article/details/110533218
上一篇: 在win2000中安装JSP
下一篇: 出走拉萨的完全攻略
推荐阅读
-
PHP网页游戏学习之Xnova(ogame)源码解读(十二)_PHP教程
-
PHP网页游戏学习之Xnova(ogame)源码解读(十四)
-
PHP网页游戏学习之Xnova(ogame)源码解读(二)_PHP教程
-
PHP网页游戏学习之Xnova(ogame)源码解读(十六)_PHP教程
-
PHP网页游戏学习之Xnova(ogame)源码解读(十三)
-
PHP网页游戏学习之Xnova(ogame)源码解读(十五)
-
PHP网页游戏学习之Xnova(ogame)源码解读(十六)
-
PHP网页游戏学习之Xnova(ogame)源码解读(十四)
-
PHP网页游戏学习之Xnova(ogame)源码解读(七)
-
PHP网页游戏学习之Xnova(ogame)源码解读(九)