Glide原理分析(二)

上一篇中主要展示了glide的一些使用,感觉glide使用起来还是非常简单的,这次是我个人第一次阅读这种开源框架代码,看起来还是有一点吃力,我只要加油了,我相信以后看的多了就会好起来的。为了方便阅读glide的时候有问题代入感,我列出了几个我想知道的问题,这次也主要按照这几个问题来说吧。

1.Glide是怎么做到加载周期跟随Fragment,Activity的周期的。

2.Glide是如何进行多线程下载的。

3.Glide是如何进行缓存的。

4.Glide是如何加载动画的。

以下是我个人对于Glide如何持有Fragment和Activity周期的简单总结。

Glide利用组件的生命周期来控制相对于其他的图片加载框架是一个很不错的功能,简单的来说Glide可以随着Fragment或者Activity的onStart,onStop,onDestory进行相应的操作,是不是和其他的图片加载框架不一样(至少我知道ImageLoder是没有办法做到的)。那让我们看一下他是怎么实现的吧。

我们打开Glide源码可以看到在manager包中有一个这样一个接口:

public interface Lifecycle {
  void addListener(LifecycleListener listener);//增加一个生命周期的监听
  void removeListener(LifecycleListener listener);//移除监听
}

我们可以现在想想一下,有了这样一个接口,我只需要在加载图片开始的时候加上这样的监听,在所在的组件onDestory时移除不就可以了,先这样想看看Glide中是怎么实现的。

LifecycleListener:
public interface LifecycleListener {
  void onStart();
  void onStop();
  void onDestroy();
}

看着是不是和组件中的很像,它就是按照组件中的来写的。这样只需要我在获取到周期的地方调用这些接口就可以实现了,Ctrl+G(Android stdio中)看看都是在那些地方使用了:


原来在这啊,哈哈,点开这个文件是这个RequestManager类实现了LifeCycleListener这个接口,在这个管理类构造函数中做了一下设置:

if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);
那这样他又是在什么地方使用,怎么就可以在组件生命周期改变可以跟着改变?不用但心Glide都做了相应的处理,获取Fragment的周期其实并不难,Glide的策略是创建一个新的无任何布局的Fragment,然后通过参数传入的Fragment对象来获取相应的周期,看看代码吧:

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public RequestManager get(android.app.Fragment fragment) {
        if (fragment.getActivity() == null) {
            throw new IllegalArgumentException(
                    "You cannot start a load on a fragment before it is attached");
        }
        if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            return get(fragment.getActivity().getApplicationContext());
        } else {
            android.app.FragmentManager fm = fragment.getChildFragmentManager();
            return fragmentGet(fragment.getActivity(), fm, fragment);
        }
    }
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
    RequestManager fragmentGet(Context context, android.app.FragmentManager fm,
                               android.app.Fragment parentHint) {
        RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
            // TODO(b/27524013): Factor out this Glide.get() call.
            Glide glide = Glide.get(context);
            requestManager =
                    new RequestManager(glide, current.getLifecycle(), current.getRequestManagerTreeNode());
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    RequestManagerFragment getRequestManagerFragment(
            final android.app.FragmentManager fm, android.app.Fragment parentHint) {
        RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
        if (current == null) {
            current = pendingRequestManagerFragments.get(fm);
            if (current == null) {
                current = new RequestManagerFragment();
                current.setParentFragmentHint(parentHint);
                pendingRequestManagerFragments.put(fm, current);
                fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
                handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
            }
        }
        return current;
    }

根据后两句代码可以看出如果现处在ui线程中,通过传入的fragment获取该fragment子对象的管理对象,然后查找是否已经存在,如果没有存在这样一个管理Glide生命周期的对象就创建一个并且将它放入传入fragment对象的管理对象中,这样就可以在这个Glide的RequestManager对象中管理Glide对象进行下载缓存等一系列操作。这就是Glide获取Fragment生命周期管理的简单流程。相比之下Activity的管理流程和这个流程是一样的,通过传入的Activity对象来获取supportFragmentManager的对象,然后新建一个Frament的子类的对象RequestManagerFragment将它添加到supportFragmentManager对象中,然后使用持有的Glide对象进行下载缓存等操作。
也许在分析和描述上很粗糙,我会在以后时间在慢慢进行完善,还请见谅。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值