code: private void tryDispatchBoundaryCallbacks(boolean post) {
          final boolean dispatchBegin = mBoundaryCallbackBeginDeferred
                  && mLowestIndexAccessed <= mConfig.prefetchDistance;
          final boolean dispatchEnd = mBoundaryCallbackEndDeferred
                  && mHighestIndexAccessed >= size() - 1 - mConfig.prefetchDistance;
  
          if (!dispatchBegin && !dispatchEnd) {
              return;
          }
  
          if (dispatchBegin) {
              mBoundaryCallbackBeginDeferred = false;
          }
          if (dispatchEnd) {
              mBoundaryCallbackEndDeferred = false;
          }
          if (post) {
              mMainThreadExecutor.execute(new Runnable() {
                  @Override
                  public void run() {
                      dispatchBoundaryCallbacks(dispatchBegin, dispatchEnd);
                  }
              });
          } else {
              dispatchBoundaryCallbacks(dispatchBegin, dispatchEnd);
          }
      }
docs: Call this when mLowest/HighestIndexAccessed are changed, or
  mBoundaryCallbackBegin/EndDeferred is set.