Make initial sync on creation of Main activity folllow recommended two-step API pattern.

This commit is contained in:
ojiikun 2013-04-05 22:08:34 +00:00
parent c87deeebac
commit 7bdd82c47d
6 changed files with 89 additions and 42 deletions

View file

@ -73,8 +73,6 @@ public abstract class ItemsList extends SherlockFragmentActivity implements Sync
return false; return false;
} }
@Override @Override
public void updateAfterSync() { public void updateAfterSync() {
if (itemListFragment != null) { if (itemListFragment != null) {
@ -85,6 +83,15 @@ public abstract class ItemsList extends SherlockFragmentActivity implements Sync
setSupportProgressBarIndeterminateVisibility(false); setSupportProgressBarIndeterminateVisibility(false);
} }
@Override
public void updatePartialSync() {
if (itemListFragment != null) {
itemListFragment.hasUpdated();
} else {
Log.e(TAG, "Error updating list as it doesn't exist.");
}
}
@Override @Override
public void updateSyncStatus(boolean syncRunning) { public void updateSyncStatus(boolean syncRunning) {
if (syncRunning) { if (syncRunning) {
@ -99,4 +106,4 @@ public abstract class ItemsList extends SherlockFragmentActivity implements Sync
} }

View file

@ -45,12 +45,17 @@ public class Main extends SherlockFragmentActivity implements StateChangedListen
if (syncFragment == null) { if (syncFragment == null) {
syncFragment = new SyncUpdateFragment(); syncFragment = new SyncUpdateFragment();
fragmentManager.beginTransaction().add(syncFragment, SyncUpdateFragment.TAG).commit(); fragmentManager.beginTransaction().add(syncFragment, SyncUpdateFragment.TAG).commit();
triggerFullRefresh(); // for our first sync, don't just trigger a heavyweight refresh, do it in two steps
// so the UI appears more quickly (per the docs at newsblur.com/api)
triggerFirstSync();
} }
} }
/**
private void triggerFullRefresh() { * Triggers an initial two-phase sync, so the UI can display quickly using /reader/feeds and
* then call /reader/refresh_feeds to get updated counts.
*/
private void triggerFirstSync() {
setSupportProgressBarIndeterminateVisibility(true); setSupportProgressBarIndeterminateVisibility(true);
if (menu != null) { if (menu != null) {
menu.findItem(R.id.menu_refresh).setEnabled(false); menu.findItem(R.id.menu_refresh).setEnabled(false);
@ -58,11 +63,14 @@ public class Main extends SherlockFragmentActivity implements StateChangedListen
final Intent intent = new Intent(Intent.ACTION_SYNC, null, this, SyncService.class); final Intent intent = new Intent(Intent.ACTION_SYNC, null, this, SyncService.class);
intent.putExtra(SyncService.EXTRA_STATUS_RECEIVER, syncFragment.receiver); intent.putExtra(SyncService.EXTRA_STATUS_RECEIVER, syncFragment.receiver);
intent.putExtra(SyncService.SYNCSERVICE_TASK, SyncService.EXTRA_TASK_FOLDER_UPDATE); intent.putExtra(SyncService.SYNCSERVICE_TASK, SyncService.EXTRA_TASK_FOLDER_UPDATE_TWO_STEP);
startService(intent); startService(intent);
} }
private void triggerRecount() { /**
* Triggers a full, manually requested refresh of feed/folder data and counts.
*/
private void triggerRefresh() {
setSupportProgressBarIndeterminateVisibility(true); setSupportProgressBarIndeterminateVisibility(true);
if (menu != null) { if (menu != null) {
menu.findItem(R.id.menu_refresh).setEnabled(false); menu.findItem(R.id.menu_refresh).setEnabled(false);
@ -95,7 +103,7 @@ public class Main extends SherlockFragmentActivity implements StateChangedListen
startActivity(profileIntent); startActivity(profileIntent);
return true; return true;
} else if (item.getItemId() == R.id.menu_refresh) { } else if (item.getItemId() == R.id.menu_refresh) {
triggerRecount(); triggerRefresh();
return true; return true;
} else if (item.getItemId() == R.id.menu_add_feed) { } else if (item.getItemId() == R.id.menu_add_feed) {
Intent intent = new Intent(this, SearchForFeeds.class); Intent intent = new Intent(this, SearchForFeeds.class);
@ -129,15 +137,29 @@ public class Main extends SherlockFragmentActivity implements StateChangedListen
} }
} }
@Override /**
* Called after the sync service completely finishes a task.
*/
@Override
public void updateAfterSync() { public void updateAfterSync() {
folderFeedList.hasUpdated(); folderFeedList.hasUpdated();
setSupportProgressBarIndeterminateVisibility(false); setSupportProgressBarIndeterminateVisibility(false);
menu.findItem(R.id.menu_refresh).setEnabled(true); menu.findItem(R.id.menu_refresh).setEnabled(true);
} }
/**
* Called when the sync service has made enough progress to update the UI but not
* enough to stop the progress indicator.
*/
@Override
public void updatePartialSync() {
folderFeedList.hasUpdated();
}
@Override @Override
public void updateSyncStatus(boolean syncRunning) { public void updateSyncStatus(boolean syncRunning) {
// TODO: the progress bar is activated manually elsewhere in this activity. this
// interface method may be redundant.
if (syncRunning) { if (syncRunning) {
setSupportProgressBarIndeterminateVisibility(true); setSupportProgressBarIndeterminateVisibility(true);
if (menu != null) { if (menu != null) {

View file

@ -179,6 +179,13 @@ public abstract class Reading extends SherlockFragmentActivity implements OnPage
checkStoryCount(pager.getCurrentItem()); checkStoryCount(pager.getCurrentItem());
} }
@Override
public void updatePartialSync() {
stories.requery();
readingAdapter.notifyDataSetChanged();
checkStoryCount(pager.getCurrentItem());
}
public abstract void checkStoryCount(int position); public abstract void checkStoryCount(int position);
@Override @Override

View file

@ -11,7 +11,8 @@ import com.newsblur.service.DetachableResultReceiver.Receiver;
import com.newsblur.service.SyncService; import com.newsblur.service.SyncService;
public class SyncUpdateFragment extends Fragment implements Receiver { public class SyncUpdateFragment extends Fragment implements Receiver {
public static final String TAG = "SyncUpdateFragment";
public static final String TAG = SyncUpdateFragment.class.getName();
public DetachableResultReceiver receiver; public DetachableResultReceiver receiver;
public boolean syncRunning = false; public boolean syncRunning = false;
@ -40,6 +41,12 @@ public class SyncUpdateFragment extends Fragment implements Receiver {
((SyncUpdateFragmentInterface) getActivity()).updateAfterSync(); ((SyncUpdateFragmentInterface) getActivity()).updateAfterSync();
} }
break; break;
case SyncService.STATUS_PARTIAL_PROGRESS:
syncRunning = true;
if (getActivity() != null) {
((SyncUpdateFragmentInterface) getActivity()).updatePartialSync();
}
break;
case SyncService.STATUS_FINISHED_CLOSE: case SyncService.STATUS_FINISHED_CLOSE:
syncRunning = false; syncRunning = false;
if (getActivity() != null) { if (getActivity() != null) {
@ -57,11 +64,11 @@ public class SyncUpdateFragment extends Fragment implements Receiver {
break; break;
case SyncService.STATUS_ERROR: case SyncService.STATUS_ERROR:
syncRunning = false; syncRunning = false;
Log.e(TAG, "There was an error"); Log.e(this.getClass().getName(), "Sync completed with an error.");
break; break;
default: default:
syncRunning = false; syncRunning = false;
Log.e(TAG, "Unrecognised response attempting to get reading data"); Log.e(this.getClass().getName(), "Sync completed with an unknown result.");
break; break;
} }
} }
@ -75,6 +82,7 @@ public class SyncUpdateFragment extends Fragment implements Receiver {
public interface SyncUpdateFragmentInterface { public interface SyncUpdateFragmentInterface {
public void updateAfterSync(); public void updateAfterSync();
public void updatePartialSync();
public void closeAfterUpdate(); public void closeAfterUpdate();
public void setNothingMoreToUpdate(); public void setNothingMoreToUpdate();
public void updateSyncStatus(boolean syncRunning); public void updateSyncStatus(boolean syncRunning);

View file

@ -451,10 +451,6 @@ public class APIManager {
} }
} }
public boolean getFolderFeedMapping() {
return getFolderFeedMapping(false);
}
public boolean getFolderFeedMapping(boolean doUpdateCounts) { public boolean getFolderFeedMapping(boolean doUpdateCounts) {
final APIClient client = new APIClient(context); final APIClient client = new APIClient(context);
@ -462,9 +458,6 @@ public class APIManager {
final FeedFolderResponse feedUpdate = new FeedFolderResponse(response.responseString, gson); final FeedFolderResponse feedUpdate = new FeedFolderResponse(response.responseString, gson);
if (response.responseCode == HttpStatus.SC_OK && !response.hasRedirected) { if (response.responseCode == HttpStatus.SC_OK && !response.hasRedirected) {
if (feedUpdate.folders.size() == 0) {
return false;
}
HashMap<String, Feed> existingFeeds = getExistingFeeds(); HashMap<String, Feed> existingFeeds = getExistingFeeds();

View file

@ -46,17 +46,18 @@ public class SyncService extends IntentService {
public static final String EXTRA_TASK_PAGE_NUMBER = "page"; public static final String EXTRA_TASK_PAGE_NUMBER = "page";
public static final String EXTRA_TASK_MULTIFEED_IDS = "multi_feedids"; public static final String EXTRA_TASK_MULTIFEED_IDS = "multi_feedids";
public final static int STATUS_RUNNING = 0x02; // TODO: replace these with enums
public final static int STATUS_RUNNING = 0x02;
public final static int STATUS_FINISHED = 0x03; public final static int STATUS_FINISHED = 0x03;
public final static int STATUS_ERROR = 0x04; public final static int STATUS_ERROR = 0x04;
public static final int STATUS_NO_MORE_UPDATES = 0x05; public static final int STATUS_NO_MORE_UPDATES = 0x05;
public static final int STATUS_FINISHED_CLOSE = 0x06; public static final int STATUS_FINISHED_CLOSE = 0x06;
public static final int NOT_RUNNING = 0x01; public static final int NOT_RUNNING = 0x01;
public static final int STATUS_PARTIAL_PROGRESS = 0x07;
public static final int EXTRA_TASK_FOLDER_UPDATE = 30; public static final int EXTRA_TASK_FOLDER_UPDATE_TWO_STEP = 30;
public static final int EXTRA_TASK_FOLDER_UPDATE_WITH_COUNT = 41; public static final int EXTRA_TASK_FOLDER_UPDATE_WITH_COUNT = 41;
public static final int EXTRA_TASK_FEED_UPDATE = 31; public static final int EXTRA_TASK_FEED_UPDATE = 31;
public static final int EXTRA_TASK_REFRESH_COUNTS = 32;
public static final int EXTRA_TASK_MARK_STORY_READ = 33; public static final int EXTRA_TASK_MARK_STORY_READ = 33;
public static final int EXTRA_TASK_SOCIALFEED_UPDATE = 34; public static final int EXTRA_TASK_SOCIALFEED_UPDATE = 34;
public static final int EXTRA_TASK_MARK_SOCIALSTORY_READ = 35; public static final int EXTRA_TASK_MARK_SOCIALSTORY_READ = 35;
@ -90,35 +91,29 @@ public class SyncService extends IntentService {
if (receiver != null) { if (receiver != null) {
receiver.send(STATUS_RUNNING, Bundle.EMPTY); receiver.send(STATUS_RUNNING, Bundle.EMPTY);
} }
// TODO: is it ever valid for receiver to be null? if not, we could factor out all
// the checks below
Log.d( this.getClass().getName(), "Sync Intent: " + intent.getIntExtra(SYNCSERVICE_TASK , -1) ); Log.d( this.getClass().getName(), "Sync Intent: " + intent.getIntExtra(SYNCSERVICE_TASK , -1) );
switch (intent.getIntExtra(SYNCSERVICE_TASK , -1)) { switch (intent.getIntExtra(SYNCSERVICE_TASK , -1)) {
case EXTRA_TASK_FOLDER_UPDATE:
if (!apiManager.getFolderFeedMapping()) { case EXTRA_TASK_FOLDER_UPDATE_TWO_STEP:
receiver.send(STATUS_NO_MORE_UPDATES, null); // do a quick fetch of folders/feeds
} apiManager.getFolderFeedMapping(false);
// notify UI of progress
if (receiver != null) {
receiver.send(STATUS_PARTIAL_PROGRESS, Bundle.EMPTY);
}
// update feed counts
apiManager.refreshFeedCounts();
// UI will be notified again by default
break; break;
case EXTRA_TASK_FOLDER_UPDATE_WITH_COUNT: case EXTRA_TASK_FOLDER_UPDATE_WITH_COUNT:
apiManager.getFolderFeedMapping(true); apiManager.getFolderFeedMapping(true);
break; break;
// For the moment, we only retry offline updates when we refresh counts. We also assume here that every update is to mark a story as read.
case EXTRA_TASK_REFRESH_COUNTS:
Cursor cursor = getContentResolver().query(FeedProvider.OFFLINE_URI, null, null, null, null);
while (cursor.moveToNext()) {
OfflineUpdate update = OfflineUpdate.fromCursor(cursor);
ArrayList<String> storyId = new ArrayList<String>();
storyId.add(update.arguments[1]);
if (apiManager.markStoryAsRead(update.arguments[0], storyId)) {
getContentResolver().delete(FeedProvider.OFFLINE_URI, DatabaseConstants.UPDATE_ID + " = ?", new String[] { Integer.toString(update.id) });
}
}
apiManager.refreshFeedCounts();
cursor.close();
break;
case EXTRA_TASK_MARK_STORY_READ: case EXTRA_TASK_MARK_STORY_READ:
final String feedId = intent.getStringExtra(EXTRA_TASK_FEED_ID); final String feedId = intent.getStringExtra(EXTRA_TASK_FEED_ID);
final ArrayList<String> storyIds = intent.getStringArrayListExtra(EXTRA_TASK_STORY_ID); final ArrayList<String> storyIds = intent.getStringArrayListExtra(EXTRA_TASK_STORY_ID);
@ -263,4 +258,19 @@ public class SyncService extends IntentService {
} }
} }
/* TODO: this code existed in the refresh_feeds intent, but was never used. Now that
we are actually using the API as intended, it is possible this needs to
actually get called somewhere.
Cursor cursor = getContentResolver().query(FeedProvider.OFFLINE_URI, null, null, null, null);
while (cursor.moveToNext()) {
OfflineUpdate update = OfflineUpdate.fromCursor(cursor);
ArrayList<String> storyId = new ArrayList<String>();
storyId.add(update.arguments[1]);
if (apiManager.markStoryAsRead(update.arguments[0], storyId)) {
getContentResolver().delete(FeedProvider.OFFLINE_URI, DatabaseConstants.UPDATE_ID + " = ?", new String[] { Integer.toString(update.id) });
}
}
cursor.close();
*/
} }