/** | |
* This Activity displays the screen's UI, creates a TaskFragment | |
* to manage the task, and receives progress updates and results | |
* from the TaskFragment when they occur. | |
*/ | |
public class MainActivity extends Activity implements TaskFragment.TaskCallbacks { | |
private static final String TAG_TASK_FRAGMENT = "task_fragment"; | |
private TaskFragment mTaskFragment; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.main); | |
FragmentManager fm = getFragmentManager(); | |
mTaskFragment = (TaskFragment) fm.findFragmentByTag(TAG_TASK_FRAGMENT); | |
// If the Fragment is non-null, then it is currently being | |
// retained across a configuration change. | |
if (mTaskFragment == null) { | |
mTaskFragment = new TaskFragment(); | |
fm.beginTransaction().add(mTaskFragment, TAG_TASK_FRAGMENT).commit(); | |
} | |
// TODO: initialize views, restore saved state, etc. | |
} | |
// The four methods below are called by the TaskFragment when new | |
// progress updates or results are available. The MainActivity | |
// should respond by updating its UI to indicate the change. | |
@Override | |
public void onPreExecute() { ... } | |
@Override | |
public void onProgressUpdate(int percent) { ... } | |
@Override | |
public void onCancelled() { ... } | |
@Override | |
public void onPostExecute() { ... } | |
} | |
// fragment | |
/** | |
* This Fragment manages a single background task and retains | |
* itself across configuration changes. | |
*/ | |
public class TaskFragment extends Fragment { | |
/** | |
* Callback interface through which the fragment will report the | |
* task's progress and results back to the Activity. | |
*/ | |
interface TaskCallbacks { | |
void onPreExecute(); | |
void onProgressUpdate(int percent); | |
void onCancelled(); | |
void onPostExecute(); | |
} | |
private TaskCallbacks mCallbacks; | |
private DummyTask mTask; | |
/** | |
* Hold a reference to the parent Activity so we can report the | |
* task's current progress and results. The Android framework | |
* will pass us a reference to the newly created Activity after | |
* each configuration change. | |
*/ | |
@Override | |
public void onAttach(Activity activity) { | |
super.onAttach(activity); | |
mCallbacks = (TaskCallbacks) activity; | |
} | |
/** | |
* This method will only be called once when the retained | |
* Fragment is first created. | |
*/ | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
// Retain this fragment across configuration changes. | |
setRetainInstance(true); | |
// Create and execute the background task. | |
mTask = new DummyTask(); | |
mTask.execute(); | |
} | |
/** | |
* Set the callback to null so we don't accidentally leak the | |
* Activity instance. | |
*/ | |
@Override | |
public void onDetach() { | |
super.onDetach(); | |
mCallbacks = null; | |
} | |
/** | |
* A dummy task that performs some (dumb) background work and | |
* proxies progress updates and results back to the Activity. | |
* | |
* Note that we need to check if the callbacks are null in each | |
* method in case they are invoked after the Activity's and | |
* Fragment's onDestroy() method have been called. | |
*/ | |
private class DummyTask extends AsyncTask<Void, Integer, Void> { | |
@Override | |
protected void onPreExecute() { | |
if (mCallbacks != null) { | |
mCallbacks.onPreExecute(); | |
} | |
} | |
/** | |
* Note that we do NOT call the callback object's methods | |
* directly from the background thread, as this could result | |
* in a race condition. | |
*/ | |
@Override | |
protected Void doInBackground(Void... ignore) { | |
for (int i = 0; !isCancelled() && i < 100; i++) { | |
SystemClock.sleep(100); | |
publishProgress(i); | |
} | |
return null; | |
} | |
@Override | |
protected void onProgressUpdate(Integer... percent) { | |
if (mCallbacks != null) { | |
mCallbacks.onProgressUpdate(percent[0]); | |
} | |
} | |
@Override | |
protected void onCancelled() { | |
if (mCallbacks != null) { | |
mCallbacks.onCancelled(); | |
} | |
} | |
@Override | |
protected void onPostExecute(Void ignore) { | |
if (mCallbacks != null) { | |
mCallbacks.onPostExecute(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment