在Fragment中使用Loader机制介绍

一、LoaderManagerImpl维护的成员变量:

final SparseArray<LoaderInfo> mLoaders = new SparseArray<LoaderInfo>(0);
final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>(0);

final String mWho;

Activity mActivity;

//初始化为false,在doStart()中赋为true;在doStop()和doRetain()中赋为false。
boolean mStarted;

//在doRetain()中赋为true;在finishRetain()中赋为false;
boolean mRetaining;

//目前没有看到mRetainingStarted有什么用处。
boolean mRetainingStarted;

//在创建Loader时,赋值为true,创建完成后立即修改为false。
boolean mCreatingLoader;

LoaderManagerImpl(String who, Activity activity, boolean started) {
    mWho = who; //android:fragment:0
    mActivity = activity;//com.example.loadercustom.LoaderCustom@4193b958
    mStarted = started; //false
}

二、LoadManagerImpl.initLoader()方法

public <D> Loader<D> initLoader(int id, Bundle args, 
        LoaderManager.LoaderCallbacks<D> callback) {     
    if (mCreatingLoader) {
        throw new IllegalStateException("Called while creating a loader");
    }

    LoaderInfo info = mLoaders.get(id);
    if (info == null) {
        // Loader doesn't already exist; create.
        info = createAndInstallLoader(id, args,  
               (LoaderManager.LoaderCallbacks<Object>)callback);
        } else {
            info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback;
    }

    if (info.mHaveData && mStarted) {
        // If the loader has already generated its data, report it now.
        info.callOnLoadFinished(info.mLoader, info.mData);
    }

    return (Loader<D>)info.mLoader;
}

[LoaderManagerImpl.createAndInstallLoader()]
private LoaderInfo createAndInstallLoader(int id, Bundle args,
    LoaderManager.LoaderCallbacks<Object> callback) {
    try {
        mCreatingLoader = true;
        LoaderInfo info = createLoader(id, args, callback);
        installLoader(info);
        return info;
    } finally {
        mCreatingLoader = false;
    }
}

private LoaderInfo createLoader(int id, Bundle args,
        LoaderManager.LoaderCallbacks<Object> callback) {
    LoaderInfo info = new LoaderInfo(id, args,  
            (LoaderManager.LoaderCallbacks<Object>)callback);
    Loader<Object> loader = callback.onCreateLoader(id, args);
    info.mLoader = (Loader<Object>)loader;
    return info;
}

void installLoader(LoaderInfo info) {
    //这里mStarted为false,先将LoaderInfo对象以<info.id, info>形式存入HashMap中。
   <strong> mLoaders.put(info.mId, info);</strong>
    if (mStarted) {
        // The activity will start all existing loaders in it's onStart(),
       // so only start them here if we're past that point of the activitiy's
       // life cycle.
       info.start();
    }
}

三、Fragment的onStart()中调用mLoaderManager.doStart()

[LoaderManagerImpl.doStart()]
void doStart() {
    if (mStarted) {
        RuntimeException e = new RuntimeException("here");
        e.fillInStackTrace();
        Log.w(TAG, "Called doStart when already started: " + this, e);
        return;
    }
    //LoaderManaer的mStarted,在doStart()中赋值为true,在doStop()和doRetain()中赋为false;
    //而且分别在doStart()、doStop()和doRetain()中执行时分别做了严格的异常检测。
    mStarted = true;

    // Call out to sub classes so they can start their loaders
    // Let the existing loaders know that we want to be notified when a load is complete
    //这里mLoader.size() = 1
    for (int i = mLoaders.size()-1; i >= 0; i--) {
        mLoaders.valueAt(i).start();
    }
}

四、LoaderInfo类

4.1 维护的变量及初始化

//以下4个在createLoader()中初始化
final int mId;
final Bundle mArgs;
LoaderManager.LoaderCallbacks<Object>mCallbacks;
Loader<Object> mLoader;
 
//在callOnLoadFinished()中赋为true;在destroy()中赋为false
boolean mDeliveredData;
 
//mData对象为AsyncTaskLoader类的模板类型,赋值为loadInBackground()方法的返回值。
//mData值更新后,则mHaveData赋为true。
Object mData;
boolean mHaveData;
 
//在start()中赋值true;在retain()和stop()中赋值false
boolean mStarted;
 
//在retain()中赋值true;在finishRetain()中赋为false。
boolean mRetaining;
 
//在retain()中赋为mStarted
boolean mRetainingStarted;
 
//在doReportNextStart()中赋为true
boolean mReportNextStart;
 
//在destroy()中赋为true
boolean mDestroyed;
//标志是否已注册监听,start()中注册监听并赋值true;在stop()和destroy()中解注册并赋值false
boolean mListenerRegistered;
LoaderInfo mPendingLoader;
 
public LoaderInfo(int id, Bundle args,LoaderManager.LoaderCallbacks<Object> callbacks) {
    mId = id;
    mArgs = args;
    mCallbacks = callbacks;
}
 
[LoaderManagerImpl.LoaderInfo.start()]
void start() {
    if (mRetaining &&mRetainingStarted) {
        // Our owner is started, but we were beingretained from a
        // previous instance in the startedstate...  so there is really
        // nothing to do here, since the loaders are still started.
       mStarted = true;
       return;
    }
 
   if (mStarted) {
        // If loader already started, don'trestart.
        return;
    }
 
   mStarted = true;
   if (mLoader == null && mCallbacks != null) {
        mLoader = mCallbacks.onCreateLoader(mId,mArgs);
    }
   if (mLoader != null) {
       if (mLoader.getClass().isMemberClass()
               &&!Modifier.isStatic(mLoader.getClass().getModifiers())) {
          throw newIllegalArgumentException("Object returned from onCreateLoader
                  must not be a non-static inner memberclass: "+ mLoader);
       }
       if (!mListenerRegistered) {
           mLoader.registerListener(mId, this);
           mLoader.registerOnLoadCanceledListener(this);
           mListenerRegistered = true;
       }
       mLoader.startLoading();
    }
}
 
[Loader.startLoading()]
public final void startLoading() {
    mStarted = true;
    mReset = false;
    mAbandoned = false;
    onStartLoading();//在AsyncTaskLoader的继承类中实现
}
 
//子类必须要实现onStartLoading(),一般的实现是:如果数据为null,则会调用forceLoad()方法;
//如果已经取得数据,则调用deliverResult()。
protected voidonStartLoading() {
   ...
    if (mResult != null) {
        deliverResult(mResult);
    }
   if (takeContentChanged() || mResult == null) {
       forceLoad();
    }
}
 
[Loader.forceLoad()]
public void forceLoad() {
   onForceLoad();
}
 
//子类必须实现onForceLoad()方法,这个方法在AsyncTaskLoader()中的实现如下:
[AsyncTaskLoader.onForceLoad()]
    protected voidonForceLoad() {
    super.onForceLoad();
    cancelLoad();
    mTask = new LoadTask();
    executePendingTask();
}
 
void executePendingTask() {
   if (mCancellingTask == null && mTask != null) {
       if (mTask.waiting) {
           mTask.waiting = false;
           mHandler.removeCallbacks(mTask);
       }
       if (mUpdateThrottle > 0) {
           long now = SystemClock.uptimeMillis();
           if (now < (mLastLoadCompleteTime+mUpdateThrottle)) {
                // Not yet time to do anotherload.
                if (DEBUG) Slog.v(TAG,"Waiting until "
                        +(mLastLoadCompleteTime+mUpdateThrottle)
                        + " to execute:" + mTask);
                mTask.waiting = true;
                mHandler.postAtTime(mTask,mLastLoadCompleteTime+mUpdateThrottle);
                return;
           }
       }
       if (DEBUG) Slog.v(TAG, "Executing: " + mTask);
       mTask.executeOnExecutor(mExecutor,(Void[]) null); --------------(1)
    }
}

mTask是一个AsyncTask对象,它把一部分工作放在新线程中执行。

五、在AsyncTask对象中运行多线程

final class LoadTask extends AsyncTask<Void, Void, D> implements Runnable {
    private final CountDownLatch mDone = new CountDownLatch(1);

    // Set to true to indicate that the task has been posted to a handler for
    // execution at a later time.  Used to throttle updates.
    boolean waiting;

    /* Runs on a worker thread */
    @Override
    protected D doInBackground(Void... params) {
        if (DEBUG) Slog.v(TAG, this + ">>> doInBackground");
        try {
            //onLoadInBackground()里只是调用loadInBackground(), 后者是个抽象方法,需在
            //AsyncTaskLoader的继承类中实现。
            D data = AsyncTaskLoader.this.onLoadInBackground();
            return data;
        } catch (OperationCanceledException ex) {
            if (!isCancelled()) {
                // onLoadInBackground threw a canceled exception spuriously.
                // This is problematic because it means that the LoaderManager did not
                // cancel the Loader itself and still expects to receive a result.
                // Additionally, the Loader's own state will not have been updated to
                // reflect the fact that the task was being canceled.
                // So we treat this case as an unhandled exception.
                throw ex;
            }
            return null;
        }
    }

    /* Runs on the UI thread */
    @Override
    protected void onPostExecute(D data) {
        try {
            AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
        } finally {
            mDone.countDown();
        }
    }

    /* Runs on the UI thread */
    @Override
    protected void onCancelled(D data) {
        try {
            AsyncTaskLoader.this.dispatchOnCancelled(this, data);
        } finally {
            mDone.countDown();
        }
    }

    /* Runs on the UI thread, when the waiting task is posted to a handler.
     * This method is only executed when task execution was deferred (waiting was true). */
    @Override
    public void run() {
        waiting = false;
        AsyncTaskLoader.this.executePendingTask();
    }

    /* Used for testing purposes to wait for the task to complete. */
    public void waitForLoader() {
        try {
            mDone.await();
        } catch (InterruptedException e) {
            // Ignore
        }
    }
}

void dispatchOnLoadComplete(LoadTask task, D data) {
    if (mTask != task) {
        if (DEBUG) Slog.v(TAG, "Load complete of old task, trying to cancel");
        dispatchOnCancelled(task, data);
    } else {
        if (isAbandoned()) {
            // This cursor has been abandoned; just cancel the new data.
            onCanceled(data);
        } else {
            commitContentChanged();
            mLastLoadCompleteTime = SystemClock.uptimeMillis();
            mTask = null;
            if (DEBUG) Slog.v(TAG, "Delivering result");
               deliverResult(data);
        }
    }
}

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

[LoaderInfo.onLoadComplete()]
@Override
public void onLoadComplete(Loader<Object> loader, Object data) {
    if (mData != data || !mHaveData) {
        mData = data;
        mHaveData = true;
        if (mStarted) {
            callOnLoadFinished(loader, data);
        }
    }
    ...
}

[LoaderInfo.callOnLoadFinished(]
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 {
            //mCallbacks由第三方应用来实现
            mCallbacks.onLoadFinished(loader, data);
        } finally {
            if (mActivity != null) {
                mActivity.mFragments.mNoTransactionsBecause = lastBecause;
            }
        }
        mDeliveredData = true;
    }//if
}
五、Fragment中执行mLoaderManager.doDestroy()
在Fragment的onDestroy()中会执行mLoaderManager.doDestroy()方法
void doDestroy() {
    if (!mRetaining) {
        for (int i = mLoaders.size()-1; i >= 0; i--) {
            mLoaders.valueAt(i).destroy();
        }
        mLoaders.clear();
    }  
    for (int i = mInactiveLoaders.size()-1; i >= 0; i--) {
        mInactiveLoaders.valueAt(i).destroy();
    }
    mInactiveLoaders.clear();
}

然后是LoaderInfo的destroy()
void destroy() {
    mDestroyed = true;
    boolean needReset = mDeliveredData;
    mDeliveredData = false;
    if (mCallbacks != null && mLoader != null && mHaveData && needReset) {
        String lastBecause = null;
        if (mActivity != null) {
            lastBecause = mActivity.mFragments.mNoTransactionsBecause;
            mActivity.mFragments.mNoTransactionsBecause = "onLoaderReset";
        }
        try {
            //该方法由调用者实现
            mCallbacks.onLoaderReset(mLoader);
        } finally {
            if (mActivity != null) {
                mActivity.mFragments.mNoTransactionsBecause = lastBecause;
            }
        }
    }
    mCallbacks = null;
    mData = null;
    mHaveData = false;
    if (mLoader != null) {
        if (mListenerRegistered) {
            mListenerRegistered = false;
            mLoader.unregisterListener(this);
            mLoader.unregisterOnLoadCanceledListener(this);
        }
        mLoader.reset();
    }
    if (mPendingLoader != null) {
        mPendingLoader.destroy();
    }
}

[Loader.reset()]
public void reset() {
    onReset();
    mReset = true;
    mStarted = false;
    mAbandoned = false;
    mContentChanged = false;
    mProcessingChange = false;
}

onReset()必须在Loader的子类中实现,示例如下:
@Override
protected void onReset() {
    super.onReset();
    // Ensure the loader is stopped		
    onStopLoading();
    if (mApps != null) {
        onReleaseResources(mApps);
        mApps = null;
    }

    if (mPackageObserver != null) {
        getContext().unregisterReceiver(mPackageObserver);
        mPackageObserver = null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值