fkm blog

software開発に関することを書いていきます

AndroidのLoaderのソースを読む(2)

最後にLoaderでdevliverResult()を呼んでからの動作

public class Loader<D> {
   public void deliverResult(D data) {
     if (mListener != null) {
       mListener.onLoadComplete(this, data);
     }
  }
}

listenerは確かLoaderInfoだったはず.

final class LoaderInfo implements Loader.OnLoadCompleteListener<Object> {
  @Override
  public void onLoadComplete(Loader<Object> loader, Object data) {
    if (DEBUG) Log.v(TAG, "onLoadComplete: " + this);

    if (mDestroyed) {
      if (DEBUG) Log.v(TAG, "  Ignoring load complete -- destroyed");
      return;
    }

    if (mLoaders.get(mId) != this) {
      // This data is not coming from the current active loader.
      // We don't care about it.
      if (DEBUG) Log.v(TAG, "  Ignoring load complete -- not active");
      return;
    }
    
    LoaderInfo pending = mPendingLoader;
    if (pending != null) {
      // There is a new request pending and we were just
      // waiting for the old one to complete before starting
      // it.  So now it is time, switch over to the new loader.
      if (DEBUG) Log.v(TAG, "  Switching to pending loader: " + pending);
      mPendingLoader = null;
      mLoaders.put(mId, null);
      destroy();
      installLoader(pending);
      return;
    }
    // we try to destroy it.
    if (mData != data || !mHaveData) {
      mData = data;
      mHaveData = true;
      if (mStarted) {
        callOnLoadFinished(loader, data);
      }
    }
    if (mActivity != null && !hasRunningLoaders()) {
      mActivity.mFragments.startPendingDeferredFragments();
    }
  }
}

既に破棄されていたり, 次のリクエストが来ていたら, 今回の結果は捨てる. Loaderが停止しているような状況もだめ. データに変化がない場合も通知されない.

ということは, 割と非同期で気にせずdeliverResult()は呼んでもよさそうだ.

念のため, callOnLoadFinished()も見ておこう

final class LoaderInfo implements Loader.OnLoadCompleteListener<Object> {
  void callOnLoadFinished(Loader<Object> loader, Object data) {
    if (mCallbacks != null) {
      String lastBecause = null;
      if (mActivity != null) {
        lastBecause = mActivity.mFragments.mNoTransactionsBecause;
        mActivity.mFragments.mNoTransactionsBecause = "onLoadFinished";
      }
      try {
        if (DEBUG) Log.v(TAG, "  onLoadFinished in " + loader + ": "
            + loader.dataToString(data));
        mCallbacks.onLoadFinished(loader, data);
      } finally {
        if (mActivity != null) {
          mActivity.mFragments.mNoTransactionsBecause = lastBecause;
        }
      }
      mDeliveredData = true;
    }
  }
}
||<