Agera框架

最近在泡在网上的日子看到一篇做一个有冒险精神的人!开启慢慢的agera之旅,然后就抱着学习的心态去了解啦一下。

       结合人家写的文章与源码,自己大概的了解啦agera的内部框架,在这里我就补充一点点自己所学的东西。

agera中异步调用的机制:

<span style="font-size:18px;">  @NonNull
  @Override
  public RepositoryCompiler goTo(@NonNull final Executor executor) {
    checkExpect(FLOW);
    checkGoLazyUnused();
    addGoTo(executor, directives);
    return this;
  }</span>

goto方法中传入Executor类型的参数,可以用过

<span style="font-size:18px;"><span style="white-space:pre">	</span>Executors.newCachedThreadPool();
        Executors.newFixedThreadPool(int count);
        Executors.newSingleThreadExecutor();
        Executors.newScheduledThreadPool(int count)</span>

来获取。

然后看addGoTo方法:

  static void addGoTo(@NonNull final Executor executor,
      @NonNull final List<Object> directives) {
    directives.add(GO_TO);
    directives.add(executor);
  }
directices就是一个数组,里面维护了数据流的操作以及操作的标示符

就下来就要去看directices里的数据是怎么进行操作的:

 private void runFlowFrom(final int index, final boolean asynchronously) {
    final Object[] directives = this.directives;
    final int length = directives.length;
    int i = index;
    while (0 <= i && i < length) {
      int directiveType = (Integer) directives[i];
      if (asynchronously || directiveType == GO_TO || directiveType == GO_LAZY) {
        // Check cancellation before running the next directive. This needs to be done while locked.
        // For goTo and goLazy, because they need to change the states and suspend the flow, they
        // need the lock and are therefore treated specially here.
        synchronized (this) {
          if (checkCancellationLocked()) {
            break;
          }
          if (directiveType == GO_TO) {
            setPausedAtGoToLocked(i);
            // the actual executor delivery is done below, outside the lock, to eliminate any
            // deadlock possibility.
          } else if (directiveType == GO_LAZY) {
            setLazyAndEndFlowLocked(i);
            return;
          }
        }
      }

      // A table-switch on a handful of options is a good compromise in code size and runtime
      // performance comparing to a full-fledged double-dispatch pattern with subclasses.
      switch (directiveType) {
        case GET_FROM:
          i = runGetFrom(directives, i);
          break;
        case MERGE_IN:
          i = runMergeIn(directives, i);
          break;
        case TRANSFORM:
          i = runTransform(directives, i);
          break;
        case CHECK:
          i = runCheck(directives, i);
          break;
        case GO_TO:
          i = runGoTo(directives, i);
          break;
        case SEND_TO:
          i = runSendTo(directives, i);
          break;
        case BIND:
          i = runBindWith(directives, i);
          break;
        case FILTER_SUCCESS:
          i = runFilterSuccess(directives, i);
          break;
        case END:
          i = runEnd(directives, i);
          break;
        // Missing GO_LAZY but it has already been dealt with in the synchronized block above.
      }
    }
  }

里面是通过directiveType来进行判断的

if (directiveType == GO_TO) {
            setPausedAtGoToLocked(i);
            // the actual executor delivery is done below, outside the lock, to eliminate any
            // deadlock possibility.
          } 

当directiveType为GO_TO标记时就调用setPauseAtToLocked();

 private void setPausedAtGoToLocked(final int resumeIndex) {
    lastDirectiveIndex = resumeIndex;
    runState = PAUSED_AT_GO_TO;
  }
这里首先是记录一下当前位置,这个位置的作用在后面会说到,然后就是把当前运行的状态进行改变

然后程序运行到switch语句块的逻辑,就会调用runGoTo方法:

 private int runGoTo(@NonNull final Object[] directives, final int index) {
    Executor executor = (Executor) directives[index + 1];
    executor.execute(this);
    return -1;
  }
这里就会拿到线程池来执行Runnable中的run方法,this所指的类型中实现啦Runnable接口

  /** Called from the executor of a goTo instruction to continue processing. */
  @Override
  public void run() {
    Thread myThread = currentThread();
    int index;
    synchronized (this) {
      index = lastDirectiveIndex;
      checkState(runState == PAUSED_AT_GO_TO || runState == CANCEL_REQUESTED,
          "Illegal call of Runnable.run()");
      lastDirectiveIndex = -1;

      if (checkCancellationLocked()) {
        return;
      }
      runState = RUNNING;
      // allow thread interruption (set this when still holding the lock)
      currentThread = myThread;
    }
    // leave the synchronization lock to run the rest of the flow
    runFlowFrom(continueFromGoTo(directives, index), true);
    // consume any unconsumed interrupted flag
    Thread.interrupted();
    // disallow interrupting the current thread, but chances are the next directive has started
    // asynchronously, so check currentThread is still this thread. This also works if a goTo
    // directive is given a synchronous executor, in which case the next part of the flow will
    // have been completed by now and currentThread will have been reset by that invocation of
    // runFlowFrom().
    synchronized (this) {
      if (currentThread == myThread) {
        currentThread = null;
      }
    }
  }

在这段代码中可以看到,执行啦runFlowFrom方法

runFlowFrom(continueFromGoTo(directives, index), true);
continueFromGoTo方法中的index,就是我们上面那个setPauseATGoToLocked方法中的lastDirectiveIndex,所以在这个runFlowFrom中操作的是GoTo之后的流操作,比如:

 <span style="white-space:pre">		</span>.getFrom(supplier)
                .goTo(Executors.newSingleThreadExecutor())
                .transform(function)
getFrom中的supplier在Observable中的线程中执行,而transform中的function在Executors.newSingleThreadExecutore中执行。

这点可以从runFlowFrom的注解可以看出

// leave the synchronization lock to run the rest of the flow
离开同步锁去执行余下的部分

// disallow interrupting the current thread, but chances are the next directive has started // asynchronously, so check currentThread is still this thread. This also works if a goTo // directive is given a synchronous executor, in which case the next part of the flow will // have been completed by now and currentThread will have been reset by that invocation of // runFlowFrom().
这一段注解告诉我们,如果我们想让GoTo之后的流操作运行在别的线程池里,我们就需要在调用一次GoTo就可以啦!

综上:我们要是想在agera中进行异步操作,我们就需要把要异步的操作流放在goTo方法之后,这样后面的操作流就会运行在goTo所指定的线程池中!

对于进一步的学习可以去agera的github上学习,地址为:agera——wiki





你可能感兴趣的:(框架,android)