Last active
January 2, 2016 08:59
-
-
Save shaobin0604/8280329 to your computer and use it in GitHub Desktop.
Loader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Loader: | |
| public final void startLoading() { | |
| mStarted = true; | |
| mReset = false; | |
| mAbandoned = false; | |
| onStartLoading(); | |
| } | |
| CursorLoader: | |
| protected void onStartLoading() { | |
| if (mCursor != null) { | |
| deliverResult(mCursor); | |
| } | |
| if (takeContentChanged() || mCursor == null) { | |
| forceLoad(); | |
| } | |
| } | |
| AsynTaskLoader: | |
| protected void onForceLoad() { | |
| super.onForceLoad(); | |
| cancelLoad(); | |
| mTask = new LoadTask(); | |
| if (DEBUG) Slog.v(TAG, "Preparing load: mTask=" + mTask); | |
| executePendingTask(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| AsyncTaskLoader: | |
| 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 { | |
| D data = AsyncTaskLoader.this.onLoadInBackground(); | |
| return data; | |
| } catch (OperationCanceledException ex) { | |
| } | |
| } | |
| /* Runs on the UI thread */ | |
| @Override | |
| protected void onPostExecute(D data) { | |
| if (DEBUG) Slog.v(TAG, this + " onPostExecute"); | |
| try { | |
| AsyncTaskLoader.this.dispatchOnLoadComplete(this, data); | |
| } finally { | |
| mDone.countDown(); | |
| } | |
| } | |
| } | |
| AsyncTaskLoader: | |
| protected D onLoadInBackground() { | |
| return loadInBackground(); | |
| } | |
| CursorLoader: | |
| public Cursor loadInBackground() { | |
| try { | |
| Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection, | |
| mSelectionArgs, mSortOrder, mCancellationSignal); | |
| if (cursor != null) { | |
| // Ensure the cursor window is filled | |
| cursor.getCount(); | |
| registerContentObserver(cursor, mObserver); | |
| } | |
| return cursor; | |
| } finally { | |
| synchronized (this) { | |
| mCancellationSignal = null; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| AsyncTaskLoader: | |
| 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 { | |
| D data = AsyncTaskLoader.this.onLoadInBackground(); | |
| return data; | |
| } catch (OperationCanceledException ex) { | |
| } | |
| } | |
| /* Runs on the UI thread */ | |
| @Override | |
| protected void onPostExecute(D data) { | |
| if (DEBUG) Slog.v(TAG, this + " onPostExecute"); | |
| try { | |
| AsyncTaskLoader.this.dispatchOnLoadComplete(this, data); | |
| } finally { | |
| mDone.countDown(); | |
| } | |
| } | |
| } | |
| AsyncTaskLoader: | |
| protected D onLoadInBackground() { | |
| return loadInBackground(); | |
| } | |
| CursorLoader: | |
| public Cursor loadInBackground() { | |
| try { | |
| Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection, | |
| mSelectionArgs, mSortOrder, mCancellationSignal); | |
| if (cursor != null) { | |
| // Ensure the cursor window is filled | |
| cursor.getCount(); | |
| registerContentObserver(cursor, mObserver); | |
| } | |
| return cursor; | |
| } finally { | |
| synchronized (this) { | |
| mCancellationSignal = null; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public void onChange(boolean selfChange) { | |
| onContentChanged(); | |
| } | |
| public void onContentChanged() { | |
| if (mStarted) { | |
| forceLoad(); //这里重新发送请求. | |
| } else { | |
| // This loader has been stopped, so we don't want to load | |
| // new data right now... but keep track of it changing to | |
| // refresh later if we start again. | |
| mContentChanged = true; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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(null, mLoadersStarted, false); | |
| } | |
| mCheckedForLoaderManager = true; | |
| } | |
| getApplication().dispatchActivityStarted(this); | |
| } | |
| LoaderManagerImp: | |
| 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(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Demonstration of the use of a CursorLoader to load and display contacts | |
| * data in a fragment. | |
| */ | |
| public class LoaderCursor extends Activity { | |
| @Override | |
| protected void onCreate(Bundle savedInstanceState) { | |
| super.onCreate(savedInstanceState); | |
| FragmentManager fm = getFragmentManager(); | |
| // Create the list fragment and add it as our sole content. | |
| if (fm.findFragmentById(android.R.id.content) == null) { | |
| CursorLoaderListFragment list = new CursorLoaderListFragment(); | |
| fm.beginTransaction().add(android.R.id.content, list).commit(); | |
| } | |
| } | |
| public static class CursorLoaderListFragment extends ListFragment | |
| implements LoaderManager.LoaderCallbacks<Cursor> { | |
| // This is the Adapter being used to display the list's data. | |
| SimpleCursorAdapter mAdapter; | |
| // If non-null, this is the current filter the user has provided. | |
| String mCurFilter; | |
| @Override public void onActivityCreated(Bundle savedInstanceState) { | |
| mAdapter = new SimpleCursorAdapter(getActivity(), | |
| android.R.layout.simple_list_item_2, null, | |
| new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS }, | |
| new int[] { android.R.id.text1, android.R.id.text2 }, 0); | |
| setListAdapter(mAdapter); | |
| getLoaderManager().initLoader(0, null, this); | |
| } | |
| @Override public void onListItemClick(ListView l, View v, int position, long id) { | |
| // Insert desired behavior here. | |
| Log.i("FragmentComplexList", "Item clicked: " + id); | |
| } | |
| // These are the Contacts rows that we will retrieve. | |
| static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { | |
| Contacts._ID, | |
| Contacts.DISPLAY_NAME, | |
| Contacts.CONTACT_STATUS, | |
| Contacts.CONTACT_PRESENCE, | |
| Contacts.PHOTO_ID, | |
| Contacts.LOOKUP_KEY, | |
| }; | |
| public Loader<Cursor> onCreateLoader(int id, Bundle args) { | |
| // This is called when a new Loader needs to be created. This | |
| // sample only has one Loader, so we don't care about the ID. | |
| // First, pick the base URI to use depending on whether we are | |
| // currently filtering. | |
| Uri baseUri; | |
| if (mCurFilter != null) { | |
| baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, | |
| Uri.encode(mCurFilter)); | |
| } else { | |
| baseUri = Contacts.CONTENT_URI; | |
| } | |
| // Now create and return a CursorLoader that will take care of | |
| // creating a Cursor for the data being displayed. | |
| String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" | |
| + Contacts.HAS_PHONE_NUMBER + "=1) AND (" | |
| + Contacts.DISPLAY_NAME + " != '' ))"; | |
| return new CursorLoader(getActivity(), baseUri, | |
| CONTACTS_SUMMARY_PROJECTION, select, null, | |
| Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); | |
| } | |
| public void onLoadFinished(Loader<Cursor> loader, Cursor data) { | |
| // Swap the new cursor in. (The framework will take care of closing the | |
| // old cursor once we return.) | |
| mAdapter.swapCursor(data); | |
| // The list should now be shown. | |
| if (isResumed()) { | |
| setListShown(true); | |
| } else { | |
| setListShownNoAnimation(true); | |
| } | |
| } | |
| public void onLoaderReset(Loader<Cursor> loader) { | |
| // This is called when the last Cursor provided to onLoadFinished() | |
| // above is about to be closed. We need to make sure we are no | |
| // longer using it. | |
| mAdapter.swapCursor(null); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| 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 (mLoader != null) { | |
| if (!mListenerRegistered) { | |
| mLoader.registerListener(mId, this); | |
| mListenerRegistered = true; | |
| } | |
| mLoader.startLoading(); | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment