• Glide监听Activity生命周期源码分析


    为了分析Glide源码,我们需要先引入Glide。新建一个项目,在app.build里面引入:

    1. dependencies {
    2. implementation 'androidx.appcompat:appcompat:1.3.0'
    3. implementation 'com.google.android.material:material:1.4.0'
    4. implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    5. testImplementation 'junit:junit:4.13.2'
    6. androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    7. androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    8. implementation 'com.github.bumptech.glide:glide:3.7.0' //Glide
    9. }

    Glide基本用法:

    Glide.with(this).load(url).into(imageView);
    

    Glide的基本用法就不讲了,我们先来看Glide.with方法:

    1. public static RequestManager with(Activity activity) {
    2. RequestManagerRetriever retriever = RequestManagerRetriever.get();
    3. return retriever.get(activity);
    4. }

    RequestManager可以理解为Glide的管理类,而RequestManagerRetriever可以理解为管理RequestManager的类。我们来看下retriever的英文意思:

     我们进上面的方法第一个get看下:

    1. public static RequestManagerRetriever get() {
    2. return INSTANCE;
    3. }

    再来看下这个INSTANCE是什么东西?

    1. private static final RequestManagerRetriever
    2. INSTANCE = new RequestManagerRetriever();

    很明显,这是一个单例。

    我们再进第二个get里面看下实现:

    1. @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    2. public RequestManager get(Activity activity) {
    3. if (Util.isOnBackgroundThread() ||
    4. Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
    5. return get(activity.getApplicationContext());
    6. } else {
    7. assertNotDestroyed(activity);
    8. android.app.FragmentManager fm = activity.getFragmentManager();
    9. return fragmentGet(activity, fm);
    10. }
    11. }

    if语句里面的判断条件意思是后台线程或者SDK版本号小于11,所以我们关注else里面代码。

    断言activity没有被销毁,获取activity的FragmentManager,将activity和fm作为参数传到fragmentGet方法中:

    1. @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    2. RequestManager fragmentGet(Context context,
    3. android.app.FragmentManager fm) {
    4. RequestManagerFragment current = getRequestManagerFragment(fm);//1
    5. RequestManager requestManager = current.getRequestManager();
    6. if (requestManager == null) {
    7. requestManager = new RequestManager(context,
    8. current.getLifecycle(), current.getRequestManagerTreeNode());
    9. current.setRequestManager(requestManager);
    10. }
    11. return requestManager;
    12. }

    先来看注释1:

    1. @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    2. RequestManagerFragment getRequestManagerFragment(
    3. final android.app.FragmentManager fm) {
    4. RequestManagerFragment current =
    5. (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    6. if (current == null) {
    7. current = pendingRequestManagerFragments.get(fm);
    8. if (current == null) {
    9. current = new RequestManagerFragment();
    10. pendingRequestManagerFragments.put(fm, current);
    11. fm.beginTransaction()
    12. .add(current, FRAGMENT_TAG).commitAllowingStateLoss();
    13. handler
    14. .obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
    15. }
    16. }
    17. return current;
    18. }

    先来通过Tag找这个Fragment,如果没找到,再去pending~里面找(HashMap),如果还没有找到,就创建一个对象,然后加到activity里面。

    来看RequestManagerFragment:

    1. @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    2. public class RequestManagerFragment extends Fragment {
    3. private final ActivityFragmentLifecycle lifecycle;
    4. private RequestManager requestManager;
    5. ···
    6. public RequestManagerFragment() {
    7. this(new ActivityFragmentLifecycle());
    8. }
    9. // For testing only.
    10. @SuppressLint("ValidFragment")
    11. RequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
    12. this.lifecycle = lifecycle;
    13. }
    14. /**
    15. * Sets the current {@link com.bumptech.glide.RequestManager}.
    16. *
    17. * @param requestManager The request manager to use.
    18. */
    19. public void setRequestManager(RequestManager requestManager) {
    20. this.requestManager = requestManager;
    21. }
    22. ActivityFragmentLifecycle getLifecycle() {
    23. return lifecycle;
    24. }
    25. /**
    26. * Returns the current {@link com.bumptech.glide.RequestManager} or null if none exists.
    27. */
    28. public RequestManager getRequestManager() {
    29. return requestManager;
    30. }
    31. @Override
    32. public void onStart() {
    33. super.onStart();
    34. lifecycle.onStart();
    35. }
    36. @Override
    37. public void onStop() {
    38. super.onStop();
    39. lifecycle.onStop();
    40. }
    41. @Override
    42. public void onDestroy() {
    43. super.onDestroy();
    44. lifecycle.onDestroy();
    45. }
    46. ···
    47. }

    只保留了一些核心代码,一起来看下这些核心代码解释。

    我们再来重点看RequestManager的构造方法:

    1. new RequestManager(context,
    2. current.getLifecycle(), current.getRequestManagerTreeNode());
    3. public RequestManager(Context context, Lifecycle lifecycle,
    4. RequestManagerTreeNode treeNode) {
    5. this(context, lifecycle, treeNode,
    6. new RequestTracker(), new ConnectivityMonitorFactory());
    7. }
    8. RequestManager(Context context,
    9. final Lifecycle lifecycle,
    10. RequestManagerTreeNode treeNode,
    11. RequestTracker requestTracker,
    12. ConnectivityMonitorFactory factory) {
    13. this.context = context.getApplicationContext();
    14. this.lifecycle = lifecycle;
    15. this.treeNode = treeNode;
    16. this.requestTracker = requestTracker;
    17. this.glide = Glide.get(context);
    18. this.optionsApplier = new OptionsApplier();
    19. ConnectivityMonitor connectivityMonitor = factory.build(context,
    20. new RequestManagerConnectivityListener(requestTracker));
    21. // If we're the application level request manager, we may be created on a background thread. In that case we
    22. // cannot risk synchronously pausing or resuming requests, so we hack around the issue by delaying adding
    23. // ourselves as a lifecycle listener by posting to the main thread. This should be entirely safe.
    24. if (Util.isOnBackgroundThread()) {
    25. new Handler(Looper.getMainLooper()).post(new Runnable() {
    26. @Override
    27. public void run() {
    28. lifecycle.addListener(RequestManager.this);
    29. }
    30. });
    31. } else {
    32. lifecycle.addListener(this);//1
    33. }
    34. lifecycle.addListener(connectivityMonitor);
    35. }

    传入了此Fragment的lifecycle,很明显这个lifecycle就是ActivityFragmentLifecycle。

    我们再来看下这个类的源码:

    1. class ActivityFragmentLifecycle implements Lifecycle {
    2. private final Set lifecycleListeners =
    3. Collections
    4. .newSetFromMap(new WeakHashMap());
    5. private boolean isStarted;
    6. private boolean isDestroyed;
    7. @Override
    8. public void addListener(LifecycleListener listener) {
    9. lifecycleListeners.add(listener);
    10. if (isDestroyed) {
    11. listener.onDestroy();
    12. } else if (isStarted) {
    13. listener.onStart();
    14. } else {
    15. listener.onStop();
    16. }
    17. }
    18. void onStart() {
    19. isStarted = true;
    20. for (LifecycleListener
    21. lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
    22. lifecycleListener.onStart();
    23. }
    24. }
    25. void onStop() {
    26. isStarted = false;
    27. for (LifecycleListener
    28. lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
    29. lifecycleListener.onStop();
    30. }
    31. }
    32. void onDestroy() {
    33. isDestroyed = true;
    34. for (LifecycleListener
    35. lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
    36. lifecycleListener.onDestroy();
    37. }
    38. }
    39. }

    我们来理一理:Glide.with()里面传入一个activity,with方法里面先通过单例获取一个RequestManagerRetriever对象,然后通过这个对象的get方法获取一个RequestManager对象。

    而RequestManager初始化的时候传入的Lifecycle对象会调用addListener将RequestManager传入。我们来看RequestManagerFragment的生命周期里面调用:

    1. @Override
    2. public void onStart() {
    3. super.onStart();
    4. lifecycle.onStart();
    5. }
    6. @Override
    7. public void onStop() {
    8. super.onStop();
    9. lifecycle.onStop();
    10. }
    11. @Override
    12. public void onDestroy() {
    13. super.onDestroy();
    14. lifecycle.onDestroy();
    15. }

    每当fragment这几个生命周期触发的时候,就会调用ActivityFragmentLifecycle的对应方法。

    1. void onStart() {
    2. isStarted = true;
    3. for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
    4. lifecycleListener.onStart();
    5. }
    6. }
    7. void onStop() {
    8. isStarted = false;
    9. for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
    10. lifecycleListener.onStop();
    11. }
    12. }
    13. void onDestroy() {
    14. isDestroyed = true;
    15. for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
    16. lifecycleListener.onDestroy();
    17. }
    18. }

    这里面有调用了LifecycleListener的对应方法,典型的接口回调。Util.getSnapshot代码:

    1. public static List getSnapshot(Collection other) {
    2. List result = new ArrayList(other.size());
    3. for (T item : other) {
    4. result.add(item);
    5. }
    6. return result;
    7. }

    将Set转化成集合,其实目前的使用来看这个集合就一个对象,就是RequestManager对象。我们才想RequestManager肯定实现了LifecycleListener接口:

    1. RequestManager implements LifecycleListener
    2. @Override
    3. public void onStart() {
    4. resumeRequests();
    5. }
    6. @Override
    7. public void onStop() {
    8. pauseRequests();
    9. }
    10. @Override
    11. public void onDestroy() {
    12. requestTracker.clearRequests();
    13. }

    来做一个总结吧:通过Glide.with(Activity activity)会获取一个RequestManager对象,具体with方法是这样的:先通过单例获取一个RequestManagerRetriever,然后调用这个对象的get方法返回一个RequestManager对象,这个get方法里面又获取了activity的FragmentManager,然后又将activity和这个fm传入fragmentGet方法中,这个fragmentGet里面创建了一个无界面的fragment,然后这个fargment里面持有ActivityFragmentLifecycle,这个lifecycle就监听了无界面fragment的生命周期。fragmentGet里面还做了一件事,就是将这个获取到的fragment再拿到这个fragment的lifecycle,传入RequestManager构造并返回RequestManager对象。RequestManager构造里面有一个lifecycle.addListener方法很重要,将RequestManager对象本身传入。这样fragment生命周期变化->lifecyle对应方法触发->lifecycleListener接口回调->lifecycleListener接口实现类RequestManager对应方法触发。

  • 相关阅读:
    PostgreSQL创建表空间及用户授权
    我开源了团队内部基于SpringBoot Web快速开发的API脚手架v1.6.0更新
    STM32G030F6 (SOP-20)Cortex ® -M0+, 32KB Flash, 8KB RAM, 17 GPIOs
    springboot进行微信公众号相关开发:(三)发送模板消息并设置通用回调消息接收接口
    API安全
    提莫的idea的bug是真滴多
    Ethereum Classic的难度计算|猿创征文
    php __destruct反序列化原理
    组合数据类型——元组列表集合映射,含词频统计做法
    NPDP考试需要携带什么?文具携带说明
  • 原文地址:https://blog.csdn.net/qq_36428821/article/details/126217157