标签:
一. 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