IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Glide源码解析2 -- 生命周期原理 -> 正文阅读

[移动开发]Glide源码解析2 -- 生命周期原理

一 概述

Glide 中一个重要的特性就是Request可以绑定Activity或者fragment的onStart而resume,onStop而pause,onDestroy而clear,所以Glide可以节约流量内存,防止内存泄露,但是要注意不要传入在with()方法里传入application,不然就没办法对生命周期进行管理了。

二 核心类

  1. RequestManager:实现了LifeCycleListener,主要作用是结合Activity或者Fragment的生命周期,对Request进行管理,其中关联的方法有pauseRequests(), resumeRequests(), clearRequests()。
  2. RequestManagerRetriever:获取RequestManager,和SupportRequestManagerFragment,并将二者绑定,从而在fragment的生命周期方法中可回调到RequestManager对request进行生命周期管理的相应方法。
  3. SupportRequestManagerFragment, 空白Fragment,与RequestManager进行了绑定,作用为提供Fragment生命周期管理方法入口,如onStart(), onStop(), onDestroy()。
  4. ActivityFragmentLifecycle, 管理LifecycleListener, 空白Fragment会回调它的onStart(), onStop(), onDestroy()
  5. LifecycleListener,接口,定义生命周期管理方法,onStart(), onStop(), onDestroy(). RequestManager实现了它。

三 如何绑定生命周期

我们来看一下关键代码Glide.with()这个方法

  //传入一个Context
  public static RequestManager with(@NonNull Context context)
  //传入一个activity
  public static RequestManager with(@NonNull Activity activity)
  //传入一个FragmentActivity 
  public static RequestManager with(@NonNull FragmentActivity activity)
  //传入一个Fragment
  public static RequestManager with(@NonNull Fragment fragment)
  //传入一个View
  public static RequestManager with(@NonNull View view)

这里with()方法虽然重载了很多方法,但是只分为两类:

  • 传入一个ApplicationContext,Glide的生命周期就相当于绑定了整个应用,只要应用不退出,任何时候都能够加载,也可以理解为不对Glide生命周期进行管理。
  • 传入activity、FragmentActivity 、Fragment 及View
    ,这样就会创建一个看不见的fragment,Glide的生命周期就随着该Fragment的变化而变化

2.1 传入参数为ApplicationContext时

public static RequestManager with(@NonNull Context context) {
    return getRetriever(context).get(context);
  }
  //由于传入参数是ApplicationContext,所以最终调用getApplicationManager方法。
  public RequestManager get(@NonNull Context context) {
    if (context == null) {
      throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
      if (context instanceof FragmentActivity) {
        //判断context类型是不是FragmentActivity
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
        //判断context类型是不是Activity
        return get((Activity) context);
      } else if (context instanceof ContextWrapper) {
        //判断context类型是不是ContextWrapper
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
    //context类型属于ApplicationContext
    return getApplicationManager(context);
  }

因为传入的是ApplicationContext参数类型,所以最终调用了getApplicationManager()方法:

private RequestManager getApplicationManager(Context context) {
    // Either an application context or we're on a background thread.
    if (applicationManager == null) {
        synchronized (this) {
            if (applicationManager == null) {
                // Normally pause/resume is taken care of by the fragment we add to the fragment or activity.
                // However, in this case since the manager attached to the application will not receive lifecycle
                // events, we must force the manager to start resumed using ApplicationLifecycle.
                applicationManager = new RequestManager(context.getApplicationContext(),
                        new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
            }
        }
    }

    return applicationManager;
}

这里传入了ApplicationLifecycle来管理生命周期,但是看ApplicationLifecycle源码,只有一个addListener()方法,所以不起控制作用,只有整个app进程退出,Glide的request的生命周期才结束,这显然不是什么优点,所以我们主要来看一下传入Activity或者Fragment的效果

2.2 传入参数类型为Activity为例

Glide.java:

public static RequestManager with(Activity activity) {
	//单例获取RequestManagerRetriever 
    RequestManagerRetriever retriever = RequestManagerRetriever.get();
    //讲activity作为参数传入RequestManagerRetriever的get方法,得到RequestManager
    return retriever.get(activity);
}

RequestManagerRetriever.java:

public RequestManager get(Activity activity) {
    if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        return get(activity.getApplicationContext());
    } else {
        assertNotDestroyed(activity);
        //获取FragmentManager ,管理fragment的类
        android.app.FragmentManager fm = activity.getFragmentManager();
        return fragmentGet(activity, fm);
    }
}

如果当前是在子线程,则不需要对Glide生命周期进行管理,否则将通过fragmentGet方法创建一个fragment。

RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
	//创建或者获取fragment
    RequestManagerFragment current = getRequestManagerFragment(fm);
    //在这个fragment里获取RequestManager 
    RequestManager requestManager = current.getRequestManager();
    //如果当前的fragment是新创建的,并没有requestManager,则new一个,并且把fragment的Lifecycle传入requestManager
    if (requestManager == null) {
    	//创建RequestManager
        requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
        //给新创建的fragment设置requestManager 
        current.setRequestManager(requestManager);
    }
    return requestManager;
}

我们来看一下getRequestManagerFragment()这个方法:

RequestManagerFragment getRequestManagerFragment(final android.app.FragmentManager fm) {
//这里先会根据Tag获取一下fragment,避免重复创建
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
   		 //如果tag没找到,则在HashMap中取出fm
        current = pendingRequestManagerFragments.get(fm);
        //如果还是没有,则new一个
        if (current == null) {
            current = new RequestManagerFragment();
            //放入到HashMap
            pendingRequestManagerFragments.put(fm, current);
            //把新建的fragment添加到activity
            fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
            //同时发送消息把FragmentManager移除,因为不需要了
            handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
        }
    }
    return current;
}

从fm中去查找tag为FRAGMENT_TAG的fragment是否存在,如果不存在就从pendingRequestManagerFragments这个HashMap中去取,如果没有就创建一个fragment,添加到pendingRequestManagerFragments并且将该fragment绑定到activity,绑定成功后则从pendingRequestManagerFragments移除fragment。这里的pendingRequestManagerFragments主要是防止fragment重复创建,因为每个activity必须对应一个唯一的fragment。来看一下这个fragment的实现RequestManagerFragment。

public class RequestManagerFragment extends Fragment {
  private final ActivityFragmentLifecycle lifecycle;
  public SupportRequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }
  public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
  }
  ...
  @NonNull
  ActivityFragmentLifecycle getGlideLifecycle() {
    return lifecycle;
  }
  ...
  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();
  }

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

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

这里将新建一个ActivityFragmentLifecycle,赋值给RequestManagerFragment的 this.lifecycle,在当前fragment的生命周期方法里,会调用ActivityFragmentLifecycle的对应的方法,我们来看一下ActivityFragmentLifecycle:

ActivityFragmentLifecycle.java:

class ActivityFragmentLifecycle implements Lifecycle {
    @Override
    public void addListener(LifecycleListener listener) {
        lifecycleListeners.add(listener);

        if (isDestroyed) {
            listener.onDestroy();
        } else if (isStarted) {
            listener.onStart();
        } else {
            listener.onStop();
        }
    }

    void onStart() {
        isStarted = true;
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onStart();
        }
    }

    void onStop() {
        isStarted = false;
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onStop();
        }
    }

    void onDestroy() {
        isDestroyed = true;
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onDestroy();
        }
    }
}

在ActivityFragmentLifecycle生命周期方法里,会有一个监听回调,调用LifecycleListener对应的生命周期方法,我们在前面说过RequestManager是管理Glide的Request生命周期的管理类,那么在这里我们很自然就联想到,RequestManager应该是实现了LifecycleListener这个接口,才能实现管理的功能,我们来验证一下:

我们倒回去看看RequestManagerRetriever的fragmentGet方法

RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
    RequestManagerFragment current = getRequestManagerFragment(fm);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
    	//这里创建了RequestManager,留意这里传去了fragment的Lifecycle
        requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
        current.setRequestManager(requestManager);
    }
    return requestManager;
}

在创建RequestManager的时候传入了新建的RequestManagerFragment的Lifecycle,也就是上面说过的ActivityFragmentLifecycle,我们来看一下RequestManager的构造方法:

RequestManager.java:

//RequestManager 实现了LifecycleListener,证实了上面所说
public class RequestManager implements LifecycleListener,

  ModelTypes<RequestBuilder<Drawable>> {
 public RequestManager(Context context, Lifecycle lifecycle, RequestManagerTreeNode treeNode) {
        this(context, lifecycle, treeNode, new RequestTracker(), new ConnectivityMonitorFactory());
    }

    RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
            RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
        this.context = context.getApplicationContext();
        //这里将传入的ActivityFragmentLifecycle赋值给RequestManager的lifecycle 
        this.lifecycle = lifecycle;
        
        if (Util.isOnBackgroundThread()) {
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                	//这里调用ActivityFragmentLifecycle的addListener,将RequestManager作为ActivityFragmentLifecycle的LifecycleListener
                    lifecycle.addListener(RequestManager.this);
                }
            });
        } else {
            lifecycle.addListener(this);
        }
        lifecycle.addListener(connectivityMonitor);
    }
}

在创建RequestManager的时候,传入了RequestManagerFragment的Lifecycle(ActivityFragmentLifecycle),赋值给RequestManager自己的lifecycle,同时调用ActivityFragmentLifecycle的addListener()方法,把自己作为监听器赋值给ActivityFragmentLifecycle的LifecycleListener。

四 总结

总的来说,当主界面是Activity或者是Fragment的时候,Glide在调用with()方法的时候,会将其作为参数传去,然后Glide会通过RequestManagerRetriever创建一个空白的fragment(RequestManagerFragment),将这个空白的fragment添加到主界面中,这样生命周期就和主界面绑定了;在这个fragment里,会new一个实现了Lifecycle的
ActivityFragmentLifecycle,在调用空白fragment的生命周期方法的同时,会调用ActivityFragmentLifecycle对应的方法,而在ActivityFragmentLifecycle的生命周期方法里,会回调一个监听器对应的方法(LifecycleListener),这个监听器在RequestManagerRetriever这个类里创建RequestManager里被赋值,所以这里通过回调,实现了主界面生命周期和RequestManager实现了绑定。而RequestManager里是通过requestTracker这个类来管理Glide的Request的,代码比较简单,这里就不细说了。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-19 17:44:27  更:2021-11-19 17:46:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:48:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码