在Fragment中使用Loader机制介绍

来源:互联网 发布:r230清零软件图解 编辑:程序博客网 时间:2024/06/10 20:12

一、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()中赋为falseboolean mDeliveredData; //mData对象为AsyncTaskLoader类的模板类型,赋值为loadInBackground()方法的返回值。//mData值更新后,则mHaveData赋为true。Object mData;boolean mHaveData; //在start()中赋值true;在retain()和stop()中赋值falseboolean mStarted; //在retain()中赋值true;在finishRetain()中赋为false。boolean mRetaining; //在retain()中赋为mStartedboolean mRetainingStarted; //在doReportNextStart()中赋为trueboolean mReportNextStart; //在destroy()中赋为trueboolean mDestroyed;//标志是否已注册监听,start()中注册监听并赋值true;在stop()和destroy()中解注册并赋值falseboolean 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()]@Overridepublic 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的子类中实现,示例如下:@Overrideprotected 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;    }}
0 0
原创粉丝点击