美文网首页
Glide源码浅析(四)生命周期下的请求

Glide源码浅析(四)生命周期下的请求

作者: 小川君 | 来源:发表于2018-09-30 09:49 被阅读0次

在RequestManagerRetriever中创建了Fragment并与ReqyestManager相关联
RequestManagerRetriever#fragmentGet():

  @NonNull
  private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable 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 =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

首先通过getRequestManagerFragment创建了一个Fragment,首次创建的话,fragment里面并没有包含requestManager,所以hui进入判断体
通过factory创建一个RequestManager

RequestManagerFactory不用多说,用于创建RequestManager
Lifecycle 有两个子类 ApplicationLifecycle和ActivityFragmentLifecycle,ApplicationLifecycle只有一个开始的监听,因为是全局所以只有在应用退出的时候才会有停止状态,ActivityFragmentLifecycle则有开始、停止和销毁三种情况,并且还又移除监听的接口,分别在fragment的onStart()onstop()和onDestroy()进行调用

RquestManagerFragment#

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

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

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

ActivityFragmentLifecycle#

  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();
   }
 }

我们可以看到每一个生命周期里面都会调用lifecyclerListener中对应的方法,

  @Override
  public void addListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.add(listener);

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

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

ActivityFragmentLifecycle提供了新增和删除监听的两个方法
addListener
在RequestManager的构造器中 调用了这个方法

    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

如果是在主线程中加载的图片,会将RequestManager自身加入监听,并且会加入一个connectivityMonitor监听
ConnectivityMonitorFactory 创建网络监听的工厂类,子类为DefaultConnectivityMonitorFactory
DefaultConnectivityMonitorFactory#build():

  @NonNull
  @Override
  public ConnectivityMonitor build(
      @NonNull Context context,
      @NonNull ConnectivityMonitor.ConnectivityListener listener) {
    int permissionResult = ContextCompat.checkSelfPermission(context, NETWORK_PERMISSION);
    boolean hasPermission = permissionResult == PackageManager.PERMISSION_GRANTED;
    if (Log.isLoggable(TAG, Log.DEBUG)) {
      Log.d(
          TAG,
          hasPermission
              ? "ACCESS_NETWORK_STATE permission granted, registering connectivity monitor"
              : "ACCESS_NETWORK_STATE permission missing, cannot register connectivity monitor");
    }
    return hasPermission
        ? new DefaultConnectivityMonitor(context, listener) : new NullConnectivityMonitor();
  }

这里会根据是否有网络权限来创建两个不同的类监听器,NullConnectivityMonitor没有任何的逻辑实现 DefaultConnectivityMonitor
DefaultConnectivityMonitor#...


  @Override
  public void onStart() {
    register();
  }

  @Override
  public void onStop() {
    unregister();
  }

  @Override
  public void onDestroy() {
    // Do nothing.
  }
  
    private final BroadcastReceiver connectivityReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(@NonNull Context context, Intent intent) {
      boolean wasConnected = isConnected;
      isConnected = isConnected(context);
      if (wasConnected != isConnected) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "connectivity changed, isConnected: " + isConnected);
        }

        listener.onConnectivityChanged(isConnected);
      }
    }
  };

注册和反注册就是针对网络观察者,网络发生变化之后会调用listener.onConnectivityChanged()

在RequestManager的构造器中:

    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));

RequestManager#

 private static class RequestManagerConnectivityListener implements ConnectivityMonitor
      .ConnectivityListener {
    private final RequestTracker requestTracker;

    RequestManagerConnectivityListener(@NonNull RequestTracker requestTracker) {
      this.requestTracker = requestTracker;
    }

    @Override
    public void onConnectivityChanged(boolean isConnected) {
      if (isConnected) {
        requestTracker.restartRequests();
      }
    }
  }

根据网络的连接状态进行处理,如果是连接状态则调用requestTracker.restartRequests();
RequestTracker 源码中的注释表述的很完全:用于跟踪、取消和重新启动在已完成和失败的请求的类,并且只能在主线程中访问。
RequestTracker#restartRequests():

  public void restartRequests() {
    for (Request request : Util.getSnapshot(requests)) {
      if (!request.isComplete() && !request.isCancelled()) {
        // Ensure the request will be restarted in onResume.
        request.pause();
        if (!isPaused) {
          request.begin();
        } else {
          pendingRequests.add(request);
        }
      }
    }
  }

首先遍历请求集合,如果遍历到的秦秋没有完成也没有被取消,那么就先暂停,如果此时的请求正在执行,那么就重新启动,如果此时的 请求本来就再暂停状态,那么就放入到等待队列中

removeListener
RequestManager本身实现了Lifecycle接口,所以就实现了onStart()、onStop()、onDestroy()
RequestManager#onDestroy():

  @Override
  public void onDestroy() {
    targetTracker.onDestroy();
    for (Target<?> target : targetTracker.getAll()) {
      clear(target);
    }
    targetTracker.clear();
    requestTracker.clearRequests();
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    mainHandler.removeCallbacks(addSelfToLifecycle);
    glide.unregisterRequestManager(this);
  }

fragment销毁的时候会做一些释放操作,清除所有与当前Fragment有关系的请求,请求所有的监听器

onStart
当fragment走到onStart的时候,会调用RequestManager的resumeRequests(),进而调用RequestTracker.resumeRequests()
这里先说一下RequestTracker中的请求集合
RequestBuilder#into()


  private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @NonNull RequestOptions options) {
    Util.assertMainThread();
    Preconditions.checkNotNull(target);
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }

    options = options.autoClone();
    Request request = buildRequest(target, targetListener, options);

    Request previous = target.getRequest();
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      request.recycle();
      // If the request is completed, beginning again will ensure the result is re-delivered,
      // triggering RequestListeners and Targets. If the request is failed, beginning again will
      // restart the request, giving it another chance to complete. If the request is already
      // running, we can let it continue running without interruption.
      if (!Preconditions.checkNotNull(previous).isRunning()) {
        // Use the previous request rather than the new one to allow for optimizations like skipping
        // setting placeholders, tracking and un-tracking Targets, and obtaining View dimensions
        // that are done in the individual Request.
        previous.begin();
      }
      return target;
    }

    requestManager.clear(target);
    target.setRequest(request);
    requestManager.track(target, request);

    return target;
  }

这个方法大家应该很属性把,就是Glide调用链的最后一步,设置Imageview;在这里面会先创建一个请求,或是从target中获取一个请求,然后调用requestManager.track()将target和request传过去
RequestManager#track()

  void track(@NonNull Target<?> target, @NonNull Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
  }

这里涉及到了一个targetTracke,作用同requestTracker一样,也实现了LifecyclerListener,不过并没有具体的实现,当然我们可以自定义Target,然后等到界面stop的时候不显示图片start的时候显示图片,虽然毫无意义,并且targetTracker同样将Target储存到了一个集合中
我们主要是看requestTracker
RequestTracker#runRequest():

  public void runRequest(@NonNull Request request) {
    requests.add(request);
    if (!isPaused) {
      request.begin();
    } else {
      pendingRequests.add(request);
    }
  }

可以看到根据当前的请求状态,对请求进行执行或是加入等待队列操作

我们来看onStart状态下的请求处理
RequestTracker#resumeRequesets():

  public void resumeRequests() {
    isPaused = false;
    for (Request request : Util.getSnapshot(requests)) {
      if (!request.isComplete() && !request.isCancelled() && !request.isRunning()) {
        request.begin();
      }
    }
    pendingRequests.clear();
  }

所有的请求开始执行

onStop

  @Override
  public void onStop() {
    for (Target<?> target : Util.getSnapshot(targets)) {
      target.onStop();
    }
  }

stop就非常的简单了

简答总结下:

先创建一个Fragment  然后在创建一个RequestManager,并将Fragment中的Lifecycle传入到RequestManager中,用于传递fragment的声明周期,Lifecycle中包含有一个生命周期的监听,fragment在生命周期切换的时候会间接的调用这个生命周期监听,而实现在RequestManager中,这样就将两个类关联了起来。而RequestManager本身实现了Lifecycle接口,所以其内部实现了onstart()、onStop()的方法;此外还有一个网络监听器ConnectivityMonitor,用于判断当前的网络状态;RequsetBuilder在设置into的时候会将Request间接的传递到RequestTracker中,便于在onStart()、onStop中进行处理      

相关文章

网友评论

      本文标题:Glide源码浅析(四)生命周期下的请求

      本文链接:https://www.haomeiwen.com/subject/lgxmoftx.html