在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
- 在Fragment中使用Loader机制介绍
- 在应用中使用Ext Loader
- 在Extjs4应用中使用Ext.Loader
- 在Extjs4应用中使用Ext.Loader
- 在Extjs4应用中使用Ext.Loader
- 在ExtJS4应用中使用Ext.Loader
- 如何在activity中使用Loader?
- 在应用中使用Ext Loader
- 在Fragment中使用GestureDetector
- 在Fragment中使用Menu
- Fragment在xml中使用
- 在fragment中使用onActivityResult
- 在Fragment中使用Listview
- swipRefresh在fragment中使用
- 在Fragment嵌套Fragment使用中,出现第二次使用空白
- 在Activity,Fragment,嵌套Fragment中使用ToolBar
- 【android】在fragment中使用option menu
- ViewPagerInFragment 在Fragment中使用ViewPager
- Android 获取assets绝对路径
- GDB使用介绍
- 二叉树宽度高度和判断是否相等
- UVA253 - Cube painting
- 在 Visual Studio 2012 中创建 ASP.Net Web Service
- 在Fragment中使用Loader机制介绍
- poj 2431 Expedition
- Python中*args 和**kwargs的用法
- 剑指offer 面试题6 重建二叉树
- Angular.js的使用原因
- Android动态加载oat文件总结一
- 设置Eclipse编码方式
- 交换x,y的三种方式
- 通过win下的eclipse连接虚拟机中伪分布的hadoop进行调试