Glide中如何实现生命周期绑定呢?
添加RequestManagerFragment RequestManagerFragment是实现Glide生命周期的关键。RequestManagerFragment是一个没有界面的Fragment,用于存放RequestManager。RequestManagerFragment可以管理(包括启动和停止)它自身所在的Fragment或Activity中的Target上关联的Glide Request。
当你调用Glide.with(activity)
时,Glide已经偷偷在这个activity中添加了一个RequestManagerFragment。
注意:Android中系统内置了一种Activity,support库提供了另一种Activity(FragmentActivity)。为了兼容不同的Activity,Glide.with()
方法有几个重载版本,对前者而言是Glide.with(android.app.Activity)
,对后者是Glide.with(android.support.v4.app.FragmentActivity)
。不同的Glide.with()
方法添加的Fragment有所不同。
Activity类型
添加的Fragment类型
android.support.v4.app.FragmentActivity
SupportRequestManagerFragment
android.app.Activity
RequestManagerFragment
Glide已经注意到其中的差异,它并不会弄混。我们只要知道其中的差异即可。下文的讨论中关注的重点是Glide”偷偷”添加Fragment的流程,而忽略了Fragment类型的差异。
Glide.with()
最终会调用到RequestManagerRetriever.get()
方法。RequestManagerRetriever.get()
源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public RequestManager get (Activity activity) { ... android.app.FragmentManager fm = activity.getFragmentManager(); return fragmentGet(activity, fm, null ); } private RequestManager fragmentGet (Context context, android.app.FragmentManager fm, android.app.Fragment parentHint) { RequestManagerFragment current = getRequestManagerFragment(fm, parentHint); RequestManager requestManager = current.getRequestManager(); if (requestManager == null ) { Glide glide = Glide.get(context); requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode()); current.setRequestManager(requestManager); } return requestManager; } 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; }
从代码可以看到调用Glide.with(activity)
时Glide的确添加了Fragment。很容易用以下代码验证是否真的添加了Fragment。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private static final String FRAGMENT_TAG = "com.bumptech.glide.manager" ;@Override protected void onCreate (@Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_target); Glide.with(this ); findViewById(R.id.button).setOnClickListener(new View .OnClickListener() { @Override public void onClick (View v) { Fragment fragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG); if (fragment instanceof SupportRequestManagerFragment) { System.out.println(fragment); } } }); }
点击Button输出如下:
1 07-15 03:53:37.272 26036-26036/? I/System.out: SupportRequestManagerFragment{ccdb477 #0 com.bumptech.glide.manager}{parent=null}
RequestManagerFragment生命周期
RequestManagerFragment - 有一个类型为ActivityFragmentLifecycle的lifecycle成员。RequestManagerFragment生命周期事件会通知给lifecycle相应的方法。
ActivityFragmentLifecycle - 有一个类型为Set的lifecycleListeners成员。onStart/onStop/onDestroy被调用时会回调lifecycleListeners中的每个listener。
RequestManager - 它实现了LifecycleListener接口,有一个类型为TargetTracker的成员。RequestManager的onStart/onStop/onDestroy被调用时会通知TargetTracker。RequestManager自身作为LifecycleListener被添加到ActivityFragmentLifecycle。
TargetTracker - 它实现了LifecycleListener接口,用于管理多个Target。TargetTracker的onStart/onStop/onDestory被调用时会通知Target。
Target - Target继承自LifecycleListener。
UI上有一个ImageView,调用Glide给这个ImageView加载一张图片,代码如下:
1 Glide.with(this ).load(...).into(imageView);
into()
方法原型是RequestBuilder.into(ImageView)
。这个方法中,ImageView会被封装成BitmapImageViewTarget。然后调用RequestBuilder.into(Target)
方法。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public <Y extends Target <TranscodeType>> Y into (@NonNull Y target) { Util.assertMainThread(); Preconditions.checkNotNull(target); if (!isModelSet) { throw new IllegalArgumentException ("You must call #load() before calling #into()" ); } Request previous = target.getRequest(); if (previous != null ) { requestManager.clear(target); } requestOptions.lock(); Request request = buildRequest(target); target.setRequest(request); requestManager.track(target, request); return target; }
整理出来的流程是这样的:
1 2 3 4 5 6 Glide.with() -> RequestManagerRetriever.get() -> RequestManager.load() -> RequestBuilder.into() -> RequestManager.track() -> TargetTracker.track() ->
通过应用中的一个场景来理解RequestManagerFragment生命周期过程。假设用户按Home键退出应用中某个正在加载图片的页面,有以下流程:
1 2 3 4 5 RequestManagerFragment.onStop() -> ActivityFragmentLifecycle.onStop() -> RequestManager.onStop() -> TargetTracker.onStop() -> Target.onStop() ->
ActivityFragmentLifecycle如何跟RequestManager关联上的呢?关键在于这段代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 private RequestManager fragmentGet (Context context, android.app.FragmentManager fm, android.app.Fragment parentHint) { RequestManagerFragment current = getRequestManagerFragment(fm, parentHint); RequestManager requestManager = current.getRequestManager(); if (requestManager == null ) { Glide glide = Glide.get(context); requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode()); current.setRequestManager(requestManager); } return requestManager; } private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory () { @Override public RequestManager build (Glide glide, Lifecycle lifecycle, RequestManagerTreeNode requestManagerTreeNode) { return new RequestManager (glide, lifecycle, requestManagerTreeNode); } }; public class RequestManagerFragment extends Fragment { private final ActivityFragmentLifecycle lifecycle; public RequestManagerFragment () { this (new ActivityFragmentLifecycle ()); } RequestManagerFragment(ActivityFragmentLifecycle lifecycle) { this .lifecycle = lifecycle; } ActivityFragmentLifecycle getGlideLifecycle () { return lifecycle; } }
梳理一下我们不难发现,RequestManager的lifecycle成员跟RequestManagerFragment的lifecycle是同一个对象!
RequestManagerFragment的数量
有几个RequestManagerFragment?
有几个RequestManager?
多个RequestManagerFragment之间是什么关系?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class RequestManagerRetriever implements Handler .Callback { final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments = new HashMap <>(); private RequestManager fragmentGet (Context context, android.app.FragmentManager fm, android.app.Fragment parentHint) { RequestManagerFragment current = getRequestManagerFragment(fm, parentHint); RequestManager requestManager = current.getRequestManager(); if (requestManager == null ) { Glide glide = Glide.get(context); requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode()); current.setRequestManager(requestManager); } return requestManager; } }
先来回答前两个问题。有n个Activity/Fragment使用Glide加载图片的话,则有n个RequestManagerFragment和n个RequestManager。即,每个Activity/Fragment中会被添加一个TAG为”com.bumptech.glide.manager”的RequestManageFragment,RequestManageFragment和RequestManager是一一对应关系。
第3个问题稍麻烦一点。考虑这样一种情况,一个Activity中有两个Fragment,它们都在使用Glide加载图片。一共有3个RequestManagerFragment,它们的关系如下:
1 2 3 4 5 6 public class RequestManagerFragment extends Fragment { private final HashSet<RequestManagerFragment> childRequestManagerFragments = new HashSet <>(); @Nullable private RequestManagerFragment rootRequestManagerFragment; }
Glide 如何触发 onTrimMemory() 流程如下图:
Glide 如何触发 onStop()
其他事件的传递过程也类似。如下图: