标签:
一. LoaderManager的使用public class MainActivity extends Activity { private String TAG = "LoaderManager"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getLoaderManager().initLoader(0, null, mCallback); } private final LoaderManager.LoaderCallbacks<Cursor> mCallback = new LoaderCallbacks<Cursor>() { @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { // TODO Auto-generated method stub android.util.Log.v(TAG, "LoaderCallbacks-------onCreateLoader"); return new CursorLoader(getApplicationContext(), Telephony.MmsSms.CONTENT_CONVERSATIONS_URI, null, null, null, null); //return null; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // TODO Auto-generated method stub android.util.Log.v(TAG, "LoaderCallbacks-------onLoadFinished----count:"+data.getCount()); while(data.moveToNext()){ android.util.Log.v(TAG,":"+data.getString(data.getColumnIndex("address"))); android.util.Log.v(TAG,":"+data.getString(data.getColumnIndex("body"))); } } @Override public void onLoaderReset(Loader<Cursor> loader) { // TODO Auto-generated method stub android.util.Log.v(TAG, "LoaderCallbacks-------onCreateLoader"); } }; }
1.LoaderManager
那么为什么要实现LoaderCallbacks类呢(回调机制),我们等会再说。先来看看怎么获取LoaderManage对象----getLoaderManager():我们可以看到,Activity.java和Fragment.java中都有这个方法,说明我们在创建每一个Activity和Fragment的时候,都会生成一个相对应的LoaderManager对象。当然,在显式的调用getLoaderManager()的时候,如果先前没有创建过LoaderManager对象,它会直接new LoaderManagerImpl()并返回这个对象。如果先前已经创建过LoaderManager对象,那么就会直接使用以前的LoaderManager对象。public LoaderManager getLoaderManager() { if (mLoaderManager != null) { return mLoaderManager; } mCheckedForLoaderManager = true; mLoaderManager = getLoaderManager(null, mLoadersStarted, true); return mLoaderManager; } LoaderManagerImpl getLoaderManager(String who, boolean started, boolean create) { if (mAllLoaderManagers == null) { mAllLoaderManagers = new HashMap<String, LoaderManagerImpl>(); } LoaderManagerImpl lm = mAllLoaderManagers.get(who); if (lm == null) { if (create) { lm = new LoaderManagerImpl(who, this, started); mAllLoaderManagers.put(who, lm); } } else { lm.updateActivity(this); } return lm; }
protected void onStart() { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this); mCalled = true; if (!mLoadersStarted) { mLoadersStarted = true; if (mLoaderManager != null) { mLoaderManager.doStart(); } else if (!mCheckedForLoaderManager) { mLoaderManager = getLoaderManager(null, mLoadersStarted, false); } mCheckedForLoaderManager = true; } getApplication().dispatchActivityStarted(this); }
由于LoaderManager是一个抽象类,所以它的子类LoaderManagerImpl必须要实现它的几个抽象方法。而这几个抽象方法使用了LoaderCallbacks类型的变量作为形参,所以,我们要自己实现LoaderCallbacks这个接口。那么,initLoader和restartLoader这两个方法是干嘛用的呢?要了解这个,我们必须先得了解Loader.java这个类。
public void deliverResult(D data) { if (mListener != null) { mListener.onLoadComplete(this, data); } }
而这个接口的实现对象mListener是被registerListener()传进来的。
public void registerListener(int id, OnLoadCompleteListener<D> listener) { if (mListener != null) { throw new IllegalStateException("There is already a listener registered"); } mListener = listener; mId = id; }再来看看实现它的地方,是在LoaderManager的内部实现类LoaderManagerImpl中,如下:
final class LoaderInfo implements Loader.OnLoadCompleteListener<Object>,Loader.OnLoadCanceledListener<Object>
volatile LoadTask mTask; final class LoadTask extends AsyncTask<Void, Void, D> implements RunnableonForceLoad():重载
@Override protected void onForceLoad() { super.onForceLoad(); cancelLoad(); mTask = new LoadTask(); if (DEBUG) Slog.v(TAG, "Preparing load: mTask=" + mTask); executePendingTask(); } void dispatchOnCancelled(LoadTask task, D data) { onCanceled(data); if (mCancellingTask == task) { if (DEBUG) Slog.v(TAG, "Cancelled task is now canceled!"); mLastLoadCompleteTime = SystemClock.uptimeMillis(); mCancellingTask = null; if (DEBUG) Slog.v(TAG, "Delivering cancellation"); deliverCancellation(); executePendingTask(); } }
protected D doInBackground(Void... params) { if (DEBUG) Slog.v(TAG, this + " >>> doInBackground"); try { D data = AsyncTaskLoader.this.onLoadInBackground(); if (DEBUG) Slog.v(TAG, this + " <<< doInBackground"); return data; } catch (OperationCanceledException ex) { if (!isCancelled()) { throw ex; } if (DEBUG) Slog.v(TAG, this + " <<< doInBackground (was canceled)"); return null; } } protected D onLoadInBackground() { return loadInBackground(); } public abstract D loadInBackground();
public Cursor loadInBackground() { Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection, mSelectionArgs, mSortOrder); if (cursor != null) { // Ensure the cursor window is filled cursor.getCount(); cursor.registerContentObserver(mObserver); } return cursor; }
protected void onPostExecute(D data) { if (DEBUG) Slog.v(TAG, this + " onPostExecute"); try { AsyncTaskLoader.this.dispatchOnLoadComplete(this, data); } finally { mDone.countDown(); } } 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 { mLastLoadCompleteTime = SystemClock.uptimeMillis(); mTask = null; if (DEBUG) Slog.v(TAG, "Delivering result"); deliverResult(data); } } }
public void deliverResult(Cursor cursor) { if (isReset()) { // An async query came in while the loader is stopped if (cursor != null) { cursor.close(); } return; } Cursor oldCursor = mCursor; mCursor = cursor; if (isStarted()) { super.deliverResult(cursor); } if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) { oldCursor.close(); } }
Loader.java public void forceLoad() { onForceLoad(); }
@Override protected void onStartLoading() { if (mCursor != null) { deliverResult(mCursor); } if (takeContentChanged() || mCursor == null) { forceLoad(); } }
Loader.java public final void startLoading() { mStarted = true; mReset = false; mAbandoned = false; onStartLoading(); }
LoaderManager.LoaderCallbacks<Object> mCallbacks; Loader<Object> mLoader; public LoaderInfo(int id, Bundle args, LoaderManager.LoaderCallbacks<Object> callbacks) { mId = id; mArgs = args; mCallbacks = callbacks; }
<span style="font-size:14px;">final SparseArray<LoaderInfo> mLoaders = new SparseArray<LoaderInfo>(); final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>(); </span>mLoaders是一个数据集合,它保存了所有的LoaderInfo对象(封装了Loader),也就是保存了所有的Loader对象。
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 (DEBUG) Log.v(TAG, "initLoader in " + this + ": args=" + args); if (info == null) { // Loader doesn't already exist; create. info = createAndInstallLoader(id, args, (LoaderManager.LoaderCallbacks<Object>)callback); if (DEBUG) Log.v(TAG, " Created new loader " + info); } else { if (DEBUG) Log.v(TAG, " Re-using existing loader " + info); 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; }
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) { mLoaders.put(info.mId, info); 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(); } }
void start() { if (mRetaining && mRetainingStarted) { // Our owner is started, but we were being retained from a // previous instance in the started state... so there is really // nothing to do here, since the loaders are still started. mStarted = true; return; } if (mStarted) { // If loader already started, don't restart. return; } mStarted = true; if (DEBUG) Log.v(TAG, " Starting: " + this); if (mLoader == null && mCallbacks != null) { mLoader = mCallbacks.onCreateLoader(mId, mArgs); } if (mLoader != null) { if (mLoader.getClass().isMemberClass() && !Modifier.isStatic(mLoader.getClass().getModifiers())) { throw new IllegalArgumentException( "Object returned from onCreateLoader must not be a non-static inner member class: " + mLoader); } if (!mListenerRegistered) { mLoader.registerListener(mId, this); mLoader.registerOnLoadCanceledListener(this); mListenerRegistered = true; } mLoader.startLoading(); } }
LoaderManager void doStart() { if (DEBUG) Log.v(TAG, "Starting in " + this); if (mStarted) { RuntimeException e = new RuntimeException("here"); e.fillInStackTrace(); Log.w(TAG, "Called doStart when already started: " + this, e); return; } 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 for (int i = mLoaders.size()-1; i >= 0; i--) { mLoaders.valueAt(i).start(); } } Activity protected void onStart() { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this); mCalled = true; if (!mLoadersStarted) { mLoadersStarted = true; if (mLoaderManager != null) { mLoaderManager.doStart(); } else if (!mCheckedForLoaderManager) { mLoaderManager = getLoaderManager("(root)", mLoadersStarted, false); } mCheckedForLoaderManager = true; } getApplication().dispatchActivityStarted(this); }
标签:
原文地址:http://blog.csdn.net/sjz4860402/article/details/51182380