Fix issue #3: Retain progress dialog for repo update during orientation change

Do so by:

 - Making RepoDetailsFragment/RepoListFragment retain their instances
 - Move the management of the update repo dialog to UpdateReceiver
 - Let the fragments tell the UpdateReceiver when to show/hide
This commit is contained in:
Peter Serwylo 2014-07-05 09:00:11 +09:30
parent eb841a88ca
commit 5ff0ef8de7
3 changed files with 131 additions and 42 deletions

View File

@ -53,6 +53,7 @@ public class UpdateService extends IntentService implements ProgressListener {
// while the other uses progress events (string event types).
public static final String EVENT_COMPLETE_WITH_CHANGES = "repoUpdateComplete (changed)";
public static final String EVENT_COMPLETE_AND_SAME = "repoUpdateComplete (not changed)";
public static final String EVENT_FINISHED = "repoUpdateFinished";
public static final String EVENT_ERROR = "repoUpdateError";
public static final String EVENT_INFO = "repoUpdateInfo";
@ -86,16 +87,12 @@ public class UpdateService extends IntentService implements ProgressListener {
private Context context;
private ProgressDialog dialog;
private ProgressListener listener;
private String lastShownMessage = null;
public UpdateReceiver(Handler handler) {
super(handler);
}
public UpdateReceiver setContext(Context context) {
this.context = context;
return this;
}
public UpdateReceiver setDialog(ProgressDialog dialog) {
this.dialog = dialog;
return this;
@ -112,6 +109,29 @@ public class UpdateService extends IntentService implements ProgressListener {
}
}
private void ensureDialog() {
if (dialog == null) {
String title = context.getString(R.string.process_wait_title);
String message = lastShownMessage == null ? context.getString(R.string.process_update_msg) : lastShownMessage;
dialog = ProgressDialog.show(context, title, message, true, true);
dialog.setIcon(android.R.drawable.ic_dialog_info);
dialog.setCanceledOnTouchOutside(false);
}
}
public UpdateReceiver showDialog(Context context) {
this.context = context;
ensureDialog();
dialog.show();
return this;
}
public void hideDialog() {
dialog.hide();
dialog.dismiss();
dialog = null;
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
String message = resultData.getString(UpdateService.RESULT_MESSAGE);
@ -128,17 +148,24 @@ public class UpdateService extends IntentService implements ProgressListener {
finished = true;
} else if (resultCode == UpdateService.STATUS_INFO) {
forwardEvent(EVENT_INFO);
dialog.setMessage(message);
if (dialog != null) {
lastShownMessage = message;
dialog.setMessage(message);
}
}
if (finished && dialog.isShowing())
try {
dialog.dismiss();
} catch (IllegalArgumentException e) {
// sometimes dialog.isShowing() doesn't work :(
// https://stackoverflow.com/questions/19538282/view-not-attached-to-window-manager-dialog-dismiss
e.printStackTrace();
if (finished) {
forwardEvent(EVENT_FINISHED);
if (dialog.isShowing()) {
try {
dialog.dismiss();
} catch (IllegalArgumentException e) {
// sometimes dialog.isShowing() doesn't work :(
// https://stackoverflow.com/questions/19538282/view-not-attached-to-window-manager-dialog-dismiss
e.printStackTrace();
}
}
}
}
}
@ -147,15 +174,9 @@ public class UpdateService extends IntentService implements ProgressListener {
}
public static UpdateReceiver updateRepoNow(String address, Context context) {
String title = context.getString(R.string.process_wait_title);
String message = context.getString(R.string.process_update_msg);
ProgressDialog dialog = ProgressDialog.show(context, title, message, true, true);
dialog.setIcon(android.R.drawable.ic_dialog_info);
dialog.setCanceledOnTouchOutside(false);
Intent intent = new Intent(context, UpdateService.class);
UpdateReceiver receiver = new UpdateReceiver(new Handler());
receiver.setContext(context).setDialog(dialog);
receiver.showDialog(context);
intent.putExtra(EXTRA_RECEIVER, receiver);
if (!TextUtils.isEmpty(address)) {
intent.putExtra(EXTRA_ADDRESS, address);

View File

@ -15,9 +15,21 @@ import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.*;
import android.widget.*;
import org.fdroid.fdroid.*;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.fdroid.fdroid.NfcNotEnabledActivity;
import org.fdroid.fdroid.ProgressListener;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider;
@ -56,7 +68,10 @@ public class RepoDetailsFragment extends Fragment {
private static final int UPDATE = 1;
private static final int ENABLE_NFC = 2;
private static final String TAG = "org.fdroid.fdroid.views.fragments.RepoDetailsFragment";
private MenuItem enableNfc = null;
private UpdateService.UpdateReceiver updateHandler = null;
// TODO: Currently initialised in onCreateView. Not sure if that is the
// best way to go about this...
@ -65,6 +80,17 @@ public class RepoDetailsFragment extends Fragment {
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (updateHandler != null) {
updateHandler.showDialog(getActivity());
}
}
@Override
public void onDetach() {
super.onDetach();
if (updateHandler != null) {
updateHandler.hideDialog();
}
}
private long getRepoId() {
@ -200,13 +226,17 @@ public class RepoDetailsFragment extends Fragment {
values.put(RepoProvider.DataColumns.IN_USE, 1);
RepoProvider.Helper.update(getActivity(), repo, values);
UpdateService.updateRepoNow(repo.address, getActivity()).setListener(new ProgressListener() {
updateHandler = UpdateService.updateRepoNow(repo.address, getActivity()).setListener(new ProgressListener() {
@Override
public void onProgress(Event event) {
if (event.type.equals(UpdateService.EVENT_COMPLETE_WITH_CHANGES)) {
repo = loadRepoDetails();
updateView((ViewGroup)getView());
}
if (event.type.equals(UpdateService.EVENT_FINISHED)) {
updateHandler = null;
}
}
});
}
@ -355,6 +385,7 @@ public class RepoDetailsFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
setRetainInstance(true);
}
@Override

View File

@ -3,7 +3,10 @@ package org.fdroid.fdroid.views.fragments;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.*;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
@ -17,10 +20,21 @@ import android.support.v4.view.MenuItemCompat;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.*;
import android.widget.*;
import org.fdroid.fdroid.*;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.ProgressListener;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService;
import org.fdroid.fdroid.compat.ClipboardCompat;
import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider;
@ -30,13 +44,12 @@ import org.fdroid.fdroid.net.MDnsHelper.RepoScanListAdapter;
import org.fdroid.fdroid.views.RepoAdapter;
import org.fdroid.fdroid.views.RepoDetailsActivity;
import javax.jmdns.ServiceInfo;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.Locale;
import javax.jmdns.ServiceInfo;
public class RepoListFragment extends ListFragment
implements LoaderManager.LoaderCallbacks<Cursor>, RepoAdapter.EnabledListener {
@ -46,10 +59,28 @@ public class RepoListFragment extends ListFragment
private final int UPDATE_REPOS = 2;
private final int SCAN_FOR_REPOS = 3;
private UpdateService.UpdateReceiver updateHandler = null;
public boolean hasChanged() {
return changed;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (updateHandler != null) {
updateHandler.showDialog(getActivity());
}
}
@Override
public void onDetach() {
super.onDetach();
if (updateHandler != null) {
updateHandler.hideDialog();
}
}
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
Uri uri = RepoProvider.getContentUri();
@ -147,23 +178,25 @@ public class RepoListFragment extends ListFragment
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Can't do this in the onCreate view, because "onCreateView" which
// returns the list view is "called between onCreate and
// onActivityCreated" according to the docs.
getListView().addHeaderView(createHeaderView(), null, false);
if (getListAdapter() == null) {
// Can't do this in the onCreate view, because "onCreateView" which
// returns the list view is "called between onCreate and
// onActivityCreated" according to the docs.
getListView().addHeaderView(createHeaderView(), null, false);
// This could go in onCreate (and used to) but it needs to be called
// after addHeaderView, which can only be called after onCreate...
repoAdapter = new RepoAdapter(getActivity(), null);
repoAdapter.setEnabledListener(this);
setListAdapter(repoAdapter);
// This could go in onCreate (and used to) but it needs to be called
// after addHeaderView, which can only be called after onCreate...
repoAdapter = new RepoAdapter(getActivity(), null);
repoAdapter.setEnabledListener(this);
setListAdapter(repoAdapter);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
}
@ -215,7 +248,7 @@ public class RepoListFragment extends ListFragment
}
private void updateRepos() {
UpdateService.updateNow(getActivity()).setListener(new ProgressListener() {
updateHandler = UpdateService.updateNow(getActivity()).setListener(new ProgressListener() {
@Override
public void onProgress(Event event) {
if (event.type.equals(UpdateService.EVENT_COMPLETE_AND_SAME) ||
@ -223,6 +256,10 @@ public class RepoListFragment extends ListFragment
// No need to prompt to update any more, we just did it!
changed = false;
}
if (event.type.equals(UpdateService.EVENT_FINISHED)) {
updateHandler = null;
}
}
});
}