Performance improvement for photoViewer
I noticed that when we bring up the photoViewer,
it always initializes the first two fragments, and
then switches to whatever fragments we actually
want to look at based upon the intent parameters.
This issue is that we were assigning the adapter
to the ViewPager before we had any cursor at all.
If we hold off on setting the adpater until we have
a cursor, then this doesn't happen. This improves
startup time of the PhotoViewActivity noticeably.
Also, made a few changes to make it easier to
extend PhotoViewActivity and PhotoViewFragment,
to change its behavior.
Change-Id: Icc4c397529bd147d0ac6818f79a48db1c4a25f32
diff --git a/src/com/android/ex/photo/Intents.java b/src/com/android/ex/photo/Intents.java
index e1e77d3..4425a32 100644
--- a/src/com/android/ex/photo/Intents.java
+++ b/src/com/android/ex/photo/Intents.java
@@ -29,7 +29,7 @@
public class Intents {
// Intent extras
public static final String EXTRA_PHOTO_INDEX = "photo_index";
- public static final String EXTRA_PHOTO_ID = "photo_id";
+ public static final String EXTRA_INITIAL_PHOTO_URI = "initial_photo_uri";
public static final String EXTRA_PHOTOS_URI = "photos_uri";
public static final String EXTRA_RESOLVED_PHOTO_URI = "resolved_photo_uri";
public static final String EXTRA_PROJECTION = "projection";
@@ -68,6 +68,8 @@
/** The index of the photo to show */
private Integer mPhotoIndex;
+ /** The URI of the initial photo to show */
+ private String mInitialPhotoUri;
/** The URI of the group of photos to display */
private String mPhotosUri;
/** The URL of the photo to display */
@@ -89,6 +91,12 @@
return this;
}
+ /** Sets the initial photo URI */
+ public PhotoViewIntentBuilder setInitialPhotoUri(String initialPhotoUri) {
+ mInitialPhotoUri = initialPhotoUri;
+ return this;
+ }
+
/** Sets the photos URI */
public PhotoViewIntentBuilder setPhotosUri(String photosUri) {
mPhotosUri = photosUri;
@@ -137,6 +145,15 @@
mIntent.putExtra(EXTRA_PHOTO_INDEX, (int) mPhotoIndex);
}
+ if (mInitialPhotoUri != null) {
+ mIntent.putExtra(EXTRA_INITIAL_PHOTO_URI, mInitialPhotoUri);
+ }
+
+ if (mInitialPhotoUri != null && mPhotoIndex != null) {
+ throw new IllegalStateException(
+ "specified both photo index and photo uri");
+ }
+
if (mPhotosUri != null) {
mIntent.putExtra(EXTRA_PHOTOS_URI, mPhotosUri);
}
diff --git a/src/com/android/ex/photo/PhotoViewActivity.java b/src/com/android/ex/photo/PhotoViewActivity.java
index 5229375..323ebc8 100644
--- a/src/com/android/ex/photo/PhotoViewActivity.java
+++ b/src/com/android/ex/photo/PhotoViewActivity.java
@@ -21,6 +21,7 @@
import android.app.ActionBar.OnMenuVisibilityListener;
import android.app.Activity;
import android.app.ActivityManager;
+import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
@@ -32,6 +33,7 @@
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v4.view.ViewPager.OnPageChangeListener;
+import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
@@ -69,6 +71,8 @@
/** The URI of the photos we're viewing; may be {@code null} */
private String mPhotosUri;
+ /** The URI of the initial photo to display */
+ private String mInitialPhotoUri;
/** The index of the currently viewed photo */
private int mPhotoIndex;
/** The query projection to use; may be {@code null} */
@@ -77,10 +81,12 @@
private int mAlbumCount = ALBUM_COUNT_UNKNOWN;
/** {@code true} if the view is empty. Otherwise, {@code false}. */
private boolean mIsEmpty;
+ /** the main root view */
+ protected View mRootView;
/** The main pager; provides left/right swipe between photos */
- private PhotoViewPager mViewPager;
+ protected PhotoViewPager mViewPager;
/** Adapter to create pager views */
- private PhotoPagerAdapter mAdapter;
+ protected PhotoPagerAdapter mAdapter;
/** Whether or not we're in "full screen" mode */
private boolean mFullScreen;
/** The set of listeners wanting full screen state */
@@ -102,6 +108,11 @@
// text.
private long mActionBarHideDelayTime;
+ protected PhotoPagerAdapter createPhotoPagerAdapter(Context context,
+ android.support.v4.app.FragmentManager fm, Cursor c, float maxScale) {
+ return new PhotoPagerAdapter(context, fm, c, maxScale);
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -136,6 +147,9 @@
if (mIntent.hasExtra(Intents.EXTRA_PHOTO_INDEX) && currentItem < 0) {
currentItem = mIntent.getIntExtra(Intents.EXTRA_PHOTO_INDEX, -1);
}
+ if (mIntent.hasExtra(Intents.EXTRA_INITIAL_PHOTO_URI) && currentItem < 0) {
+ mInitialPhotoUri = mIntent.getStringExtra(Intents.EXTRA_INITIAL_PHOTO_URI);
+ }
// Set the max initial scale, defaulting to 1x
mMaxInitialScale = mIntent.getFloatExtra(Intents.EXTRA_MAX_INITIAL_SCALE, 1.0f);
@@ -145,10 +159,10 @@
setContentView(R.layout.photo_activity_view);
// Create the adapter and add the view pager
- mAdapter = new PhotoPagerAdapter(this, getSupportFragmentManager(), null, mMaxInitialScale);
-
+ mAdapter = createPhotoPagerAdapter(this, getSupportFragmentManager(),
+ null, mMaxInitialScale);
+ mRootView = findViewById(R.id.photo_activity_root_view);
mViewPager = (PhotoViewPager) findViewById(R.id.photo_view_pager);
- mViewPager.setAdapter(mAdapter);
mViewPager.setOnPageChangeListener(this);
mViewPager.setOnInterceptTouchListener(this);
@@ -156,11 +170,13 @@
getSupportLoaderManager().initLoader(LOADER_PHOTO_LIST, null, this);
final ActionBar actionBar = getActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
- mActionBarHideDelayTime = getResources().getInteger(
- R.integer.action_bar_delay_time_in_millis);
- actionBar.addOnMenuVisibilityListener(this);
- actionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ mActionBarHideDelayTime = getResources().getInteger(
+ R.integer.action_bar_delay_time_in_millis);
+ actionBar.addOnMenuVisibilityListener(this);
+ actionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
+ }
}
@Override
@@ -276,6 +292,20 @@
} else {
mAlbumCount = data.getCount();
+ if (mInitialPhotoUri != null) {
+ int index = 0;
+ int uriIndex = data.getColumnIndex(PhotoContract.PhotoViewColumns.URI);
+ while (data.moveToNext()) {
+ String uri = data.getString(uriIndex);
+ if (TextUtils.equals(uri, mInitialPhotoUri)) {
+ mInitialPhotoUri = null;
+ mPhotoIndex = index;
+ break;
+ }
+ index++;
+ }
+ }
+
// We're paused; don't do anything now, we'll get re-invoked
// when the activity becomes active again
// TODO(pwestbro): This shouldn't be necessary, as the loader manager should
@@ -287,6 +317,9 @@
mIsEmpty = false;
mAdapter.swapCursor(data);
+ if (mViewPager.getAdapter() == null) {
+ mViewPager.setAdapter(mAdapter);
+ }
notifyCursorListeners(data);
// set the selected photo
@@ -346,6 +379,7 @@
return mViewPager.getCurrentItem() == mAdapter.getItemPosition(fragment);
}
+ @Override
public void onFragmentVisible(PhotoViewFragment fragment) {
updateActionBar(fragment);
}
diff --git a/src/com/android/ex/photo/fragments/PhotoViewFragment.java b/src/com/android/ex/photo/fragments/PhotoViewFragment.java
index abb47a0..7725523 100644
--- a/src/com/android/ex/photo/fragments/PhotoViewFragment.java
+++ b/src/com/android/ex/photo/fragments/PhotoViewFragment.java
@@ -188,7 +188,11 @@
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.photo_fragment_view, container, false);
+ initializeView(view);
+ return view;
+ }
+ protected void initializeView(View view) {
mPhotoView = (PhotoView) view.findViewById(R.id.photo_view);
mPhotoView.setMaxInitialScale(mIntent.getFloatExtra(Intents.EXTRA_MAX_INITIAL_SCALE, 1));
mPhotoView.setOnClickListener(this);
@@ -207,8 +211,6 @@
// Don't call until we've setup the entire view
setViewVisibility();
-
- return view;
}
@Override