Glide之外层生命周期监听的方法

Glide 一个重要的特点就是通过一个透明的 Fragment 来感知外层 ActivityFragment的生命周期,在 onStart 方法里面启动网络请求,onStop 里面暂停请求,onDestroy 里面解除监听并释放内存。

那么,Glide 是怎么做到这个监听事件的?

用于监听的接口

Glide 里面用于监听生命周期的接口总有两个,它们分别是 LifecycleListenerLifecycle

/**
 * 一个用来监听Fragment或Activity生命周期的回调接口
 */
public interface LifecycleListener {
    /**
     * Fragment或Activity生命周期为onStart时的回调
     */
    void onStart();
    /**
     * Fragment或Activity生命周期为onStop时的回调
     */
    void onStop();
    /**
     * Fragment或Activity生命周期为onDestroy时的回调
     */
    void onDestroy();

}

LifecycleListener 是用于回调的接口,那么 Lifecycle 呢:

/**
 * 用于监听Activity / Fragment生命周期事件的接口。
 */
public interface Lifecycle {

    /**
     * 添加生命周期方法的回调监听
     */
    void addListener(@NonNull LifecycleListener listener);

    /**
     * 移除生命周期方法的回调监听
     */
    void removeListener(@NonNull LifecycleListener listener);
}

Lifecycle 就是用来注册 LifecycleListener 的。他们的具体关联关系,可以看一下 ActivityFragmentLifecycle ,这个类是 Lifecycle 实现类:

public class ActivityFragmentLifecycle implements Lifecycle {

    /**
     * 弱引用WeakHashMap持有LifecycleListener(key)再转为Set
     * Set底层就是用Map来实现的,只保留key
     */
    private final Set<LifecycleListener> lifecycleListeners =
            Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
    /**
     * 是否start了
     */
    private boolean isStarted;
    /**
     * 是否Destroyed了
     */
    private boolean isDestroyed;

    void onStart() {
        isStarted = true;
        //由于是弱引用Map,循环需要过滤空的item
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onStart();
        }
    }

    void onStop() {
        isStarted = false;
         //由于是弱引用Map,循环需要过滤空的item
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onStop();
        }
    }

    void onDestroy() {
        isDestroyed = true;
         //由于是弱引用Map,循环需要过滤空的item
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onDestroy();
        }
    }

    /**
     * 添加监听并依据当前获取的生命周期状态来设置方法回调
     *
     * @param listener 用来监听Fragment或Activity生命周期的回调接口
     */
    @Override
    public void addListener(@NonNull LifecycleListener listener) {
        lifecycleListeners.add(listener);

        if (isDestroyed) {
            listener.onDestroy();
            return;
        }

        if (isStarted) {
            listener.onStart();
            return;
        }
        listener.onStop();
    }

    @Override
    public void removeListener(@NonNull LifecycleListener listener) {
        lifecycleListeners.remove(listener);
    }
}

上面有用到一个 Util.getSnapshot 的静态方法,它就是一个过滤操作,把集合中的空数据对象给过滤了,毕竟这里是弱引用持有

   /**
     * 复制并移除集合中的空数据,提供安全可靠的集合
     *
     * @return 一个没有空数据对象的集合
     */
    @NonNull
    public static <T> List<T> getSnapshot(@NonNull Collection<T> other) {
        List<T> result = new ArrayList<>(other.size());
        for (T item : other) {
            if (item != null) {
                result.add(item);
            }
        }
        return result;
    }

这样子一来前期准备就做好了,现在就缺一个除了感知外层生命周期就没有其他作用的 Fragment 了。

感知外层生命周期的 Fragment

Glide 里面,用来感知外层生命周期的 Fragment 总共有两个,是不是有点意外。但是 Glide 作为一个开源的 SDK 总要考虑到各种兼容的情况,而 Fragment 是分两个版本的,一个是 support v4 的兼容版本,一个则是系统原生版本,后者只支持 Android 3.0 以上。

这里我就只介绍 support v4SupportRequestManagerFragment ,不过这两个 Fragment 里面的代码其实都是一样的:

public class SupportRequestManagerFragment extends Fragment {

    private static final String TAG = "SupportRMFragment";
    private final ActivityFragmentLifecycle mLifecycle;
    private RequestManager requestManager;
    //.....
    @Override
    public void onStart() {
      super.onStart();
      lifecycle.onStart();
    }

    @Override
    public void onStop() {
        super.onStop();
        lifecycle.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        lifecycle.onDestroy();
    }
}

整个类的代码里面就没有找到 onCreateView ,因此这个 Fragment 是没有任何 UI 界面的,也就是隐形的。

监听生命周期的核心代码就上面这些,是不是还漏了什么呢?是的,这里就只看到了回调事件,那么是在哪里去添加监听的呢?

控制监听的 RequestManager

之前只说了 Lifecycle 的实现类,现在来看下 LifecycleListener 的实现类,也就是上面代码的 RequestManager 对象:

/**
 * 这个是Glide用于管理网络请求的类
 * 智能控制Glide网络请求的停止、启动和再次启动
 */
public class RequestManager implements LifecycleListener{
    //用于添加和移除监听的Lifecycle对象
    final Lifecycle lifecycle;

    /**
     * 伪构建方法,这里省略了其他参数和代码
     */
    RequestManager(Lifecycle lifecycle){
        //添加监听
        lifecycle.addListener(this);
    }

    @Override
    public void onStart() {
         //省略部分代码...
    }

    @Override
    public void onStop() {
         //省略部分代码...
    }

    @Override
    public void onDestroy() {
        //省略部分代码...
        //移除监听
        lifecycle.removeListener(this);
    }
}

这里直接在 RequestManager 的构造方法里面完成了生命周期监听的绑定,从而依据感知外层生命周期的 SupportRequestManagerFragment 启动网络请求、停止网络请求、再启动网络请求和最后的销毁工作,在 onDestroy 方法里面来移除监听,防止了内存泄露。

总结

就这么一套东西看下来,其实都很好懂,关键是需要培训自己养成这种代码的思维,与君共勉。

猜你喜欢

转载自blog.csdn.net/f409031mn/article/details/80961493