author | Sriram Ramasubramanian <sriram@mozilla.com> |
Tue, 09 Jul 2013 16:24:38 -0700 | |
changeset 143400 | a0658f1018a65f5fd2d9d5c7e6d93b1e0182a822 |
parent 143399 | fabc7deeeb21834fbae7b6bd0c5f2cfca982d09a |
child 143401 | f3f76c0ea2ce93ec8787afc7955c3d28ee1ecadf |
push id | 25130 |
push user | lrocha@mozilla.com |
push date | Wed, 21 Aug 2013 09:41:27 +0000 |
treeherder | mozilla-central@b2486721572e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | lucasr |
bugs | 891105 |
milestone | 25.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
mobile/android/base/home/BookmarksPage.java | file | annotate | diff | comparison | revisions | |
mobile/android/base/home/TopBookmarksView.java | file | annotate | diff | comparison | revisions |
--- a/mobile/android/base/home/BookmarksPage.java +++ b/mobile/android/base/home/BookmarksPage.java @@ -10,67 +10,74 @@ import org.mozilla.gecko.R; import org.mozilla.gecko.db.BrowserContract.Bookmarks; import org.mozilla.gecko.db.BrowserContract.Thumbnails; import org.mozilla.gecko.db.BrowserDB; import org.mozilla.gecko.db.BrowserDB.URLColumns; import org.mozilla.gecko.gfx.BitmapUtils; import org.mozilla.gecko.home.BookmarksListAdapter.OnRefreshFolderListener; import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; import org.mozilla.gecko.home.TopBookmarksView.Thumbnail; -import org.mozilla.gecko.util.ThreadUtils; -import org.mozilla.gecko.util.UiAsyncTask; import android.content.ContentResolver; import android.content.Context; import android.content.res.Configuration; import android.database.Cursor; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v4.app.LoaderManager; import android.support.v4.app.LoaderManager.LoaderCallbacks; +import android.support.v4.content.AsyncTaskLoader; import android.support.v4.content.Loader; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; /** * A page in about:home that displays a ListView of bookmarks. */ public class BookmarksPage extends HomeFragment { public static final String LOGTAG = "GeckoBookmarksPage"; // Cursor loader ID for list of bookmarks. private static final int BOOKMARKS_LIST_LOADER_ID = 0; // Cursor loader ID for grid of bookmarks. private static final int TOP_BOOKMARKS_LOADER_ID = 1; + // Loader ID for thumbnails. + private static final int THUMBNAILS_LOADER_ID = 2; + // Key for bookmarks folder id. private static final String BOOKMARKS_FOLDER_KEY = "folder_id"; + // Key for thumbnail urls. + private static final String THUMBNAILS_URLS_KEY = "urls"; + // List of bookmarks. private BookmarksListView mList; // Grid of top bookmarks. private TopBookmarksView mTopBookmarks; // Adapter for list of bookmarks. private BookmarksListAdapter mListAdapter; // Adapter for grid of bookmarks. private TopBookmarksAdapter mTopBookmarksAdapter; - // Callback for loaders. + // Callback for cursor loaders. private CursorLoaderCallbacks mLoaderCallbacks; + // Callback for thumbnail loader. + private ThumbnailsLoaderCallbacks mThumbnailsLoaderCallbacks; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { BookmarksListView list = (BookmarksListView) inflater.inflate(R.layout.home_bookmarks_page, container, false); mTopBookmarks = new TopBookmarksView(getActivity()); list.addHeaderView(mTopBookmarks); return list; @@ -114,16 +121,17 @@ public class BookmarksPage extends HomeF bundle.putInt(BOOKMARKS_FOLDER_KEY, folderId); getLoaderManager().restartLoader(BOOKMARKS_LIST_LOADER_ID, bundle, mLoaderCallbacks); } }); mList.setAdapter(mListAdapter); // Create callbacks before the initial loader is started. mLoaderCallbacks = new CursorLoaderCallbacks(); + mThumbnailsLoaderCallbacks = new ThumbnailsLoaderCallbacks(); // Reconnect to the loader only if present. final LoaderManager manager = getLoaderManager(); manager.initLoader(BOOKMARKS_LIST_LOADER_ID, null, mLoaderCallbacks); manager.initLoader(TOP_BOOKMARKS_LOADER_ID, null, mLoaderCallbacks); } @Override @@ -222,18 +230,28 @@ public class BookmarksPage extends HomeF mListAdapter.swapCursor(c); break; } case TOP_BOOKMARKS_LOADER_ID: { mTopBookmarksAdapter.swapCursor(c); // Load the thumbnails. - if (c.getCount() > 0) { - new LoadThumbnailsTask(getActivity(), mTopBookmarks).execute(c); + if (c.getCount() > 0 && c.moveToFirst()) { + final ArrayList<String> urls = new ArrayList<String>(); + do { + final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); + urls.add(url); + } while (c.moveToNext()); + + if (urls.size() > 0) { + Bundle bundle = new Bundle(); + bundle.putStringArrayList(THUMBNAILS_URLS_KEY, urls); + getLoaderManager().restartLoader(THUMBNAILS_LOADER_ID, bundle, mThumbnailsLoaderCallbacks); + } } break; } } } @Override public void onLoaderReset(Loader<Cursor> loader) { @@ -252,51 +270,38 @@ public class BookmarksPage extends HomeF break; } } } } } /** - * An AsyncTask to load the thumbnails from a cursor. + * An AsyncTaskLoader to load the thumbnails from a cursor. */ - private static class LoadThumbnailsTask extends UiAsyncTask<Cursor, Void, Map<String, Thumbnail>> { - private final Context mContext; - private final TopBookmarksView mView; + private static class ThumbnailsLoader extends AsyncTaskLoader<Map<String, Thumbnail>> { + private Map<String, Thumbnail> mThumbnails; + private ArrayList<String> mUrls; - public LoadThumbnailsTask(Context context, TopBookmarksView view) { - super(ThreadUtils.getBackgroundHandler()); - mContext = context; - mView = view; + public ThumbnailsLoader(Context context, ArrayList<String> urls) { + super(context); + mUrls = urls; } @Override - protected Map<String, Thumbnail> doInBackground(Cursor... params) { - // TopBookmarksAdapter's cursor. - final Cursor adapterCursor = params[0]; - if (adapterCursor == null || !adapterCursor.moveToFirst()) { - return null; - } - - final List<String> urls = new ArrayList<String>(); - do { - final String url = adapterCursor.getString(adapterCursor.getColumnIndexOrThrow(URLColumns.URL)); - urls.add(url); - } while (adapterCursor.moveToNext()); - - if (urls.size() == 0) { + public Map<String, Thumbnail> loadInBackground() { + if (mUrls == null || mUrls.size() == 0) { return null; } final Map<String, Thumbnail> thumbnails = new HashMap<String, Thumbnail>(); // Query the DB for thumbnails. - final ContentResolver cr = mContext.getContentResolver(); - final Cursor cursor = BrowserDB.getThumbnailsForUrls(cr, urls); + final ContentResolver cr = getContext().getContentResolver(); + final Cursor cursor = BrowserDB.getThumbnailsForUrls(cr, mUrls); try { if (cursor != null && cursor.moveToFirst()) { do { // Try to get the thumbnail, if cursor is valid. String url = cursor.getString(cursor.getColumnIndexOrThrow(Thumbnails.URL)); final byte[] b = cursor.getBlob(cursor.getColumnIndexOrThrow(Thumbnails.DATA)); final Bitmap bitmap = (b == null || b.length == 0 ? null : BitmapUtils.decodeByteArray(b)); @@ -308,31 +313,92 @@ public class BookmarksPage extends HomeF } } finally { if (cursor != null) { cursor.close(); } } // Query the DB for favicons for the urls without thumbnails. - for (String url : urls) { + for (String url : mUrls) { if (!thumbnails.containsKey(url)) { final Bitmap bitmap = BrowserDB.getFaviconForUrl(cr, url); if (bitmap != null) { // Favicons.scaleImage can return several different size favicons, // but will at least prevent this from being too large. thumbnails.put(url, new Thumbnail(Favicons.getInstance().scaleImage(bitmap), false)); } } } return thumbnails; } @Override - public void onPostExecute(Map<String, Thumbnail> thumbnails) { - // Check to see if the view is still attached. - if (mView.getHandler() != null) { - mView.updateThumbnails(thumbnails); + public void deliverResult(Map<String, Thumbnail> thumbnails) { + if (isReset()) { + mThumbnails = null; + return; + } + + mThumbnails = thumbnails; + + if (isStarted()) { + super.deliverResult(thumbnails); + } + } + + @Override + protected void onStartLoading() { + if (mThumbnails != null) { + deliverResult(mThumbnails); + } + + if (takeContentChanged() || mThumbnails == null) { + forceLoad(); + } + } + + @Override + protected void onStopLoading() { + cancelLoad(); + } + + @Override + public void onCanceled(Map<String, Thumbnail> thumbnails) { + mThumbnails = null; + } + + @Override + protected void onReset() { + super.onReset(); + + // Ensure the loader is stopped. + onStopLoading(); + + mThumbnails = null; + } + } + + /** + * Loader callbacks for the thumbnails on TopBookmarksView. + */ + private class ThumbnailsLoaderCallbacks implements LoaderCallbacks<Map<String, Thumbnail>> { + @Override + public Loader<Map<String, Thumbnail>> onCreateLoader(int id, Bundle args) { + return new ThumbnailsLoader(getActivity(), args.getStringArrayList(THUMBNAILS_URLS_KEY)); + } + + @Override + public void onLoadFinished(Loader<Map<String, Thumbnail>> loader, Map<String, Thumbnail> thumbnails) { + if (mTopBookmarks != null) { + mTopBookmarks.updateThumbnails(thumbnails); + } + } + + @Override + public void onLoaderReset(Loader<Map<String, Thumbnail>> loader) { + if (mTopBookmarks != null) { + mTopBookmarks.updateThumbnails(null); } } } }
--- a/mobile/android/base/home/TopBookmarksView.java +++ b/mobile/android/base/home/TopBookmarksView.java @@ -176,16 +176,20 @@ public class TopBookmarksView extends Gr } /** * Update the thumbnails returned by the db. * * @param thumbnails A map of urls and their thumbnail bitmaps. */ public void updateThumbnails(Map<String, Thumbnail> thumbnails) { + if (thumbnails == null) { + return; + } + // If there's a layout scheduled on this view, wait for it to happen // by storing the thumbnails in a cache. If not, update them right away. if (isLayoutRequested()) { mThumbnailsCache = thumbnails; return; } final int count = getAdapter().getCount();