Managing activity from DialogFragment - android

How can I call finish() and other non static methods from a DialogFragment in the activity that created it? I have tried passing messages from the OnClickLisener in the DialogFragment, to no avail.
I have a really simple app, conssting of a MainActivity and DialogFragment:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.activity);
showDialog();
}
public void showDialog() {
DialogFragment newFragment = new ConfirmDialog();
newFragment.show(getFragmentManager(), "dialog");
}
}
And the Dialog is again very simple:
public class ConfirmDialog extends DialogFragment {
#Override
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Confirm you want to continue?")
.setPositiveButton("Yes.", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//finish() MainActvity
}
})
.setNegativeButton("No.", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//Do nothing in MainActity
}
});
// Create the AlertDialog object and return it
return builder.create();
}
}

There are many options. One of them is define an interface with a single method inside.
Have the dialog caller implement that interface.
Keep a global variable pointing to the caller.
Set the variable in the onAttach(Activity activity) method.
Null that variable in the onDetach() method.
Call the variable (interface member) method in the onClick.
Example:
public class MainActivity extends Activity implements MyInterface {
// ...
#Override
public void onChoose() { finish(); }
}
And inside ConfirmDialog:
public static interface MyInterface {
public void onChoose();
}
private MyInterface mListener;
#Override
public void onAttach(Activity activity) {
mListener = (MyInterface) activity;
super.onAttach(activity);
}
#Override
public void onDetach() {
mListener = null;
super.onDetach();
}
And then call mListener.onChoose() anywhere inside your class.
I know this has been marked as accepted, but I figured I could provide more feedback to the discussion.
A note about using or not interfaces. Andy's answer works just as right as mine, hence why I said "There are many options. One of them is...".
However, the reason why I prefer interfaces for this particular problem is because most of the times you're going to extend and reuse simple/common confirmation dialogs like that. hey are too generic to be "wasted" (or worse: duplicated if different event actions arise).
Unless you are deadly sure that you are going to use that only once, for one purpose (finishing), you generally should avoid hardwiring (and simplifying) the implementation details of the Activity in your dialog class. Flexibility, abstraction and efficiency. Less code to maintain.
And yes, there is a telltale that you may need that: the public keyword that you're using, especially if it's in a self-contained class file, which begs for reuse (too). Otherwise, you should be hiding that class inside your main Activity, since the implementation details (would) relate only to that one. Also, you would be removing the public keyword.
Yes, you could use for more than one Activity, but you'd be limited to finish()ing. The interface will give you flexibility to do whatever you want in each Activity. In other words, it's up to the implementer to define how it should itself behave for that event. You self-contain implementation details.
As a sidenote, what I do is create a package with all dialogs I may need for my application. For confirmation dialogs like that, I reuse for different messages and buttons. I provide defaults, but also allow for change using setArguments. And I keep the interfaces related so I don't need to create one interface for each dialog. The implementer responds according to which dialog triggered the "dialogs callback". Flexibility, abstraction and efficiency, all while avoiding things humorously called Hydra and Royal Family. So. In the end, like I said, many options. Don't over-engineer, but don't simplify too much too early (leave room for graceful expansion).
It's more important to understand advantages and pitfalls than choosing this or the other answer.

Even though the amount of work involved to make the interface is small, I don't see why you need to call finish() from the Activity that created it. Calling finish() from within the DialogFragment itself will suffice. If you need to send info back with it as well for some reason, you could always call getActivity() and chain a method that exists in the Activity. Ultimately no matter where you call finish, it will detach the Fragment and destroy it.
Just to clarify how to call a method from your Activity in your Fragment
((YourActivity)getActivity()).someMethod(param);
You MUST caste it because Java doesn't know that Activity has whatever method you wanna call. Which ever way you decide to go with, good luck :)
cheers
EDIT
I appreciate your clarification David. In general you are correct. But to be honest in this instance, you are incorrect because of the nature of Fragments and their relationships with the Activity. Again, you will essentially be creating a listener in order to be called by a Fragment that already has an extremely close relationship with the Activity class it is being held by. Any benefits provided by not hardwiring anything through listeners is lost in this case. You will still be rewriting custom code for every Dialog. While in my method you can write a method in the Activity class in such a general way that you only ever have to write it once.
There are only two reasons I see a need to use a Listener:
1. If you are writing code that other people will be using. So you provide an easy way to give info while maintaining a certain structure (like Androids DatePickerDialog).
2. If there is no connection between two parts you are trying to maintain connected (like GUI's in Java).
So I am not trying to say that David is wrong in saying this, and I am grateful he is bringing it up because it is important for people to understand when to use them. But again, in this case the benefits he mentions are non-existent due to the connection between Fragments and the Activity class. Just wanted to clarify why I believe listeners are not necessary here.

Instead of:
.setPositiveButton("Yes.", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//finish() MainActvity
}
})
Use:
.setPositiveButton("Yes.", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// this gets the current activity.
Activity currentActivity = getActivity();
// this finish() method ends the current activity.
currentActivity.finish();
}
})

Related

Get parent activity in DialogFragment subclass before show()

I am working on an android application with many dialogs, all of which extend a custom class called "DialogFragmentBase" which extends the library's "DialogFragment". All activities use the show() method overridden in DialogFragmentBase.
I want to prevent showing the dialogs if the parent activity is backgrounded (as in receiving a phone call) since that results in the illegalStatEexception, but at the same time I don't want to guard every show() call in the application with:
if(getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED))
So I wanted to do something like this in the DialogFragmentBase:
#Override
public void show(FragmentManager manager, String tag){
List<Fragment> fragments = manager.getFragments();
if(fragments != null && fragments.size() > 0){
FragmentActivity activity = fragments.get(fragments.size()-1).getActivity();
if(activity != null && activity.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)){
super.show(manager, tag);
}
}
}
So my question is: Is accessing the previous fragment like that considered a bad practice? It does work...but I remember reading somewhere that fragments shouldn't intercommunicate. If it is indeed a bad practice, what would be a better solution that can be implemented in the DialogFragmentBase (to avoid adding guards everywhere).
Note: I tried the onSaveInstanceState solution described here, but since the DialogFragment hasn't been shown yet, the onSaveInstanceState isn't called for it at that point. Also getActivity() returns null since onAttach hasn't been called yet at that point.
Thanks!
The support library FragmentManager has an isStateSaved() method. Depending on exactly what your requirements are, you could leverage this to check if it is "safe" to show your dialogs:
#Override
public void show(FragmentManager manager, String tag) {
if (!manager.isStateSaved()) {
super.show(manager, tag);
}
}
Note that the above implementation is relatively similar to using commitAllowingStateLoss(), in that you'll silently fail to show your dialog in certain cases. But perhaps that is fine for your requirements.
Perhaps you could create a new method in your dialog base class:
public void showIfResumed(FragmentActivity activity, String tag) {
if (/* your check here, e.g. activity.getLifecycle()... */) {
show(activity.getSupportFragmentManager(), tag);
}
}
And then, in your activities, rather than calling show(getSupportFragmentManager(), TAG), you could call showIfResumed(this, TAG). You'll still have to change every call to show() to a call to showIfResumed(), but this would reduce the code duplication considerably.

Manager Class to handle multiple fragments

I have multiple fragments which does the same thing but presented in different way to the user. However, the functionality in all those fragments more like same as in delete, add etc. That said, I do not want to duplicate the code. Therefore created a manager class so that I could have the centralized code. But, the problem now is, when the user is performing an action say, when the user is deleting an item, the fragment does not get refreshed. So, I need to send the message to the fragment from the manager class to refresh the list. I have the following pseudo code to give an insight...
public class MyFragment extends Fragment{
ManagerClass mManagerClass;
private void onItemSelected() {
mManagerClass = new ManagerClass(itemId);
}
public void refreshItems() {
ItemDao.query();
}
}
public class ManagerClass {
public ManagerClass(int itemId) {
DeleteItem(itemId);
}
private void DeleteItem(int itemId) {
//when this task completes it should call the MrFragment.refreshItems();
//Keep in mind that I cannot pass the Fragment becuse this ManagerClass is designed to handle more than two fragments
//MAY BE I SHOULD DO CALLBACK BUT HOW?.... When i try to implement there several callbacks but not sure which one should I use and how...
}
}
Any help would be greatly appreciated...
I was so stupid and dumb at the time. There are multiple ways to achieve this but the quick resolutions are:
1. Have a ABSTRACT class and extend the fragment out of it or
2. Use the OBSERVER pattern
I went with the second option, Observer pattern and works like a charm!

How to desing a reusable DialogFragment

There is some questions already close to this question but they haven't been very helpful for me. So here comes a new one.
I have an Activity which has two tabs. Each tab contains a ListFragment (SherlockListFragment to be exact). One tab shows a list of shopping list objects and the other shows a list of recipe objects. Now I want to create a DialogFragment for renaming a list or a recipe or any other object I might later add to the application.
The solution provided here sounded promising but because ListFragment can not be registered to listen clicks from the dialog I should make my Activity to listen them which is not ideal because then my Fragments would not be independent.
How to get data out of a general-purpose dialog class
Ideally I would like to have my rename dialog as independent and reusable as possible. This far I have invented just one way to do this. Sending the objects className and id to the dialog and then using switch case to fetch the correct object from the database. This way the dialog would be able to update the objects name by itself (if the object has rename method). But the requery to the database sounds just dump because the ListFragment has the object already. And then the dialog would need a new case in the switch for each new kind of object.
Any ideas?
I actually just created a similar sort of dialog fragment to what you're asking about. I was for a fairly large app and it was getting kind of ridiculous the amount of dialog listeners our main activity was extending just to listen for the results of a single dialog.
In order to make something a bit more flexible I turned to using ListenableFuture from Google's Guava concurrent library.
I created the following abstract class to use:
public abstract class ListenableDialogFragment<T> extends DialogFragment implements ListenableFuture<T> {
private SettableFuture<T> _settableFuture;
public ListenableDialogFragment() {
_settableFuture = SettableFuture.create();
}
#Override
public void addListener(Runnable runnable, Executor executor) {
_settableFuture.addListener(runnable, executor);
}
#Override
public boolean cancel(boolean mayInterruptIfRunning) {
return _settableFuture.cancel(mayInterruptIfRunning);
}
#Override
public boolean isCancelled() {
return _settableFuture.isCancelled();
}
#Override
public boolean isDone() {
return _settableFuture.isDone();
}
#Override
public T get() throws InterruptedException, ExecutionException {
return _settableFuture.get();
}
#Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return _settableFuture.get(timeout, unit);
}
public void set(T value) {
_settableFuture.set(value);
}
public void setException(Throwable throwable) {
_settableFuture.setException(throwable);
}
// Resets the Future so that it can be provided to another call back
public void reset() {
_settableFuture = SettableFuture.create();
}
#Override
public void onDismiss(DialogInterface dialog) {
// Cancel the future here in case the user cancels our of the dialog
cancel(true);
super.onDismiss(dialog);
}
Using this class I'm able to create my own custom dialog fragments and use them like this:
ListenableDialogFragment<int> dialog = GetIdDialog.newInstance(provider.getIds());
Futures.addCallback(dialog, new FutureCallback<int>() {
#Override
public void onSuccess(int id) {
processId(id);
}
#Override
public void onFailure(Throwable throwable) {
if (throwable instanceof CancellationException) {
// Task was cancelled
}
processException(throwable);
}
});
This is where GetIdDialog is a custom instance of a ListenableDialogFragment. I can reuse this same dialog instance if needs be by simply calling dialog.reset in the onSuccess and onFailure methods to ensure that the internal Future gets reloaded for adding back to a callback.
I hope this helps you out.
Edit: Sorry forgot to add, in your dialog you can implement an on click listener that does something like this to trigger the future:
private class SingleChoiceListener implements DialogInterface.OnClickListener {
#Override
public void onClick(DialogInterface dialog, int item) {
int id = _ids[item];
// This call will trigger the future to fire
set(id);
dismiss();
}
}
I would maybe just using a static factory pattern of some variation to allow dynamic initialization of the DialogFragment.
private enum Operation {ADD, EDIT, DELETE}
private String title;
private Operation operation;
public static MyDialogFragment newInstance(String title, Operation operation)
{
MyDialogFragment dialogFragment = new DialogFragment();
dialogFragment.title = title; // Dynamic title
dialogFragment.operation = operation;
return dialogFragment;
}
Or.. and I would recommend this more, have a static factory method for each type of operation you will use it for. This allows different dynamic variations to be more concrete and ensures that everything works together. This also allows for informative constructors.
Eg.
public static MyDialogFragment newAddItemInstance(String title)
{
MyDialogFragment dialogFragment = new DialogFragment();
dialogFragment.title = title; // Dynamic title
return dialogFragment;
}
public static MyDialogFragment newEditItemInstance(String title)
{
MyDialogFragment dialogFragment = new DialogFragment();
dialogFragment.title = title; // Dynamic title
return dialogFragment;
}
And then of course create an interface that every calling Activity / Fragment (in which case you need to set this Fragment as the targetFragment and get reference to that target Fragment in your DialogFragment) so that the implementation is taken care of in the target Fragment and nothing to do with the DialogFragment.
Summary: There are various ways of going about this, for simplicity, I would stick with some form of static factory pattern and make clever use of interfaces to separate any the logic from the DialogFragment hence making it more reusable
EDIT: From your comment I would suggest you look at two things:
Target Fragments (See the comment I made on your question). You can invoke methods in your ListFragment from your DialogFragment.
Strategy Pattern. How does the Strategy Pattern work?. This allows you to perform the same operation (with various tailored implementation for each type) on different objects. Very useful pattern.

Update Android UI from a thread in another class

I've seen a few questions on here asking similar questions, but I've not yet seen a suitable answer. Many people have asked how to update the UI from a thread, but they're almost always in the same class as the UI.
What I'm trying to do is update the UI from a thread which has been created in another class. I've seen all of the suggestions, such as async, handlers, runnable, etc... but I've having real trouble implementing them in separate classes.
I'm trying to keep my UI class minimal and only deal with interactions with the GUI, such as when a user presses a button. Now, I've created a new thread, in a new class, which connects to a Bluetooth device, but I then want to change a button in the UI thread from being a 'connect' button to a 'disconnect' button (i.e. change the button from creating the Bluetooth socket to closing it).
What is the general way to do this? Am I thinking of this all wrong and should have everything in one class? What is the correct way to interact between the 'main' UI class and other classes/threads?
Ideally I want to be able to do other UI interactions, so some solution which allows other UI changes outside of the UI class would be great!
What I'm trying to do is update the UI from a thread which has been
created in another class. I've seen all of the suggestions, such as
async, handlers, runnable, etc... but I've having real trouble
implementing them in separate classes.
Generally for your goal i recommend to you use:
AsyncTask
IntentService with ResultReceiver
I don't think that its too tricky. Absolutely not. If you have it as separated class(es) and not as inner class(es) in some Activity class so i recommend to use constructor where you will pass context, widgets, generally whatever you want and then in correct methods(which allows UI update) update your UI.
I'm doing it because i like when i have clean classes(so UI class have only UI implementations and logic is positioned separately).
Example:
public class TaskExample extends AsyncTask<Void, Integer, Void> {
private Context c;
private Button b;
public TaskExample(Context c, Button b) {
this.c = c;
this.b = b;
}
protected Void doInBackground(Void... params) {
// some work
if (isSomethingConnected) {
publishProgress(Constants.IS_CONNECTED);
}
return null;
}
public void onProgressUpdate(Integer... params) {
switch (params[0]) {
case Constants.IS_CONNECTED:
b.setText("Connected");
break;
case Constants.ANOTHER_CONSTANT:
// another work
break;
}
}
}
Usage:
public class Main extends Activity implements View.OnClickListener {
private Button b;
public void onCreate(Bundle b) {
super.onCreate(b);
// initialise widgets and set listeners to appropriate widgets
}
public void onClick(View v) {
switch(v.getId()) {
case R.id.connectBtn:
startWorker();
break;
}
}
private void startWorker() {
TaskExample te = new TaskExample(this, b);
te.execute();
}
}
There are a couple of options. If you have access to the View you are changing and simply need to force a refresh, you can use View.postInvalidate() from any thread. If you need more complex operations, such as changing the text of a button, you should use runOnUIThread, which requires access to the Activity context. This should be simple to get - just add it as a parameter for your custom Object's constructor. With this context, you can do something like this:
activityContext.runOnUiThread(new Runnable(){
#Override
public void run() {
myButton.setText("disconnect");
}
});
Use the runOnUiThread(Runnable) method to run something on the Main thread and call the ClassName.View.invalidate() method if it is a view or just make a public method in you're Target class which handles the refreshing of the UI.

Background task, progress dialog, orientation change - is there any 100% working solution?

I download some data from internet in background thread (I use AsyncTask) and display a progress dialog while downloading. Orientation changes, Activity is restarted and then my AsyncTask is completed - I want to dismiss the progess dialog and start a new Activity. But calling dismissDialog sometimes throws an exception (probably because the Activity was destroyed and new Activity hasn't been started yet).
What is the best way to handle this kind of problem (updating UI from background thread that works even if user changes orientation)? Did someone from Google provide some "official solution"?
Step #1: Make your AsyncTask a static nested class, or an entirely separate class, just not an inner (non-static nested) class.
Step #2: Have the AsyncTask hold onto the Activity via a data member, set via the constructor and a setter.
Step #3: When creating the AsyncTask, supply the current Activity to the constructor.
Step #4: In onRetainNonConfigurationInstance(), return the AsyncTask, after detaching it from the original, now-going-away activity.
Step #5: In onCreate(), if getLastNonConfigurationInstance() is not null, cast it to your AsyncTask class and call your setter to associate your new activity with the task.
Step #6: Do not refer to the activity data member from doInBackground().
If you follow the above recipe, it will all work. onProgressUpdate() and onPostExecute() are suspended between the start of onRetainNonConfigurationInstance() and the end of the subsequent onCreate().
Here is a sample project demonstrating the technique.
Another approach is to ditch the AsyncTask and move your work into an IntentService. This is particularly useful if the work to be done may be long and should go on regardless of what the user does in terms of activities (e.g., downloading a large file). You can use an ordered broadcast Intent to either have the activity respond to the work being done (if it is still in the foreground) or raise a Notification to let the user know if the work has been done. Here is a blog post with more on this pattern.
The accepted answer was very helpful, but it doesn't have a progress dialog.
Fortunately for you, reader, I have created an extremely comprehensive and working example of an AsyncTask with a progress dialog!
Rotation works, and the dialog survives.
You can cancel the task and dialog by pressing the back button (if you want this behaviour).
It uses fragments.
The layout of the fragment underneath the activity changes properly when the device rotates.
I've toiled for a week to find a solution to this dilemma without resorting to editing the manifest file. The assumptions for this solution are:
You always need to use a progress dialog
Only one task is performed at a time
You need the task to persist when the phone is rotated and the progress dialog to be automatically dismisses.
Implementation
You will need to copy the two files found at the bottom of this post into your workspace. Just make sure that:
All your Activitys should extend BaseActivity
In onCreate(), super.onCreate() should be called after you initialize any members that need to be accessed by your ASyncTasks. Also, override getContentViewId() to provide the form layout id.
Override onCreateDialog() like usual to create dialogs managed by the activity.
See code below for a sample static inner class to make your AsyncTasks. You can store your result in mResult to access later.
final static class MyTask extends SuperAsyncTask<Void, Void, Void> {
public OpenDatabaseTask(BaseActivity activity) {
super(activity, MY_DIALOG_ID); // change your dialog ID here...
// and your dialog will be managed automatically!
}
#Override
protected Void doInBackground(Void... params) {
// your task code
return null;
}
#Override
public boolean onAfterExecute() {
// your after execute code
}
}
And finally, to launch your new task:
mCurrentTask = new MyTask(this);
((MyTask) mCurrentTask).execute();
That's it! I hope this robust solution will help someone.
BaseActivity.java (organize imports yourself)
protected abstract int getContentViewId();
public abstract class BaseActivity extends Activity {
protected SuperAsyncTask<?, ?, ?> mCurrentTask;
public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance();
if (mCurrentTask != null) {
mCurrentTask.attach(this);
if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null
&& mDialogMap.get((Integer) mCurrentTask.dialogId)) {
mCurrentTask.postExecution();
}
}
}
#Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
mDialogMap.put(id, true);
}
#Override
public Object onRetainNonConfigurationInstance() {
if (mCurrentTask != null) {
mCurrentTask.detach();
if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null
&& mDialogMap.get((Integer) mCurrentTask.dialogId)) {
return mCurrentTask;
}
}
return super.onRetainNonConfigurationInstance();
}
public void cleanupTask() {
if (mCurrentTask != null) {
mCurrentTask = null;
System.gc();
}
}
}
SuperAsyncTask.java
public abstract class SuperAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
protected BaseActivity mActivity = null;
protected Result mResult;
public int dialogId = -1;
protected abstract void onAfterExecute();
public SuperAsyncTask(BaseActivity activity, int dialogId) {
super();
this.dialogId = dialogId;
attach(activity);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mActivity.showDialog(dialogId); // go polymorphism!
}
protected void onPostExecute(Result result) {
super.onPostExecute(result);
mResult = result;
if (mActivity != null &&
mActivity.mDialogMap.get((Integer) dialogId) != null
&& mActivity.mDialogMap.get((Integer) dialogId)) {
postExecution();
}
};
public void attach(BaseActivity activity) {
this.mActivity = activity;
}
public void detach() {
this.mActivity = null;
}
public synchronized boolean postExecution() {
Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId);
if (dialogExists != null || dialogExists) {
onAfterExecute();
cleanUp();
}
public boolean cleanUp() {
mActivity.removeDialog(dialogId);
mActivity.mDialogMap.remove((Integer) dialogId);
mActivity.cleanupTask();
detach();
return true;
}
}
Did someone from Google provide some "official solution"?
Yes.
The solution is more of an application architecture proposal rather that just some code.
They proposed 3 design patterns that allows an application to work in-sync with a server, regardless of the application state (it will work even if the user finishes the app, the user changes screen, the app gets terminated, every other possible state where a background data operation could be interrumpted, this covers it)
The proposal is explained in the Android REST client applications speech during Google I/O 2010 by Virgil Dobjanschi. It is 1 hour long, but it is extremely worth watching.
The basis of it is abstracting network operations to a Service that works independently to any Activity in the application. If you're working with databases, the use of ContentResolver and Cursor would give you an out-of-the-box Observer pattern that is convenient to update UI without any aditional logic, once you updated your local database with the fetched remote data. Any other after-operation code would be run via a callback passed to the Service (I use a ResultReceiver subclass for this).
Anyway, my explanation is actually pretty vague, you should definititely watch the speech.
While Mark's (CommonsWare) answer does indeed work for orientation changes, it fails if the Activity is destroyed directly (like in the case of a phone call).
You can handle the orientation changes AND the rare destroyed Activity events by using an Application object to reference your ASyncTask.
There's an excellent explanation of the problem and the solution here:
Credit goes completely to Ryan for figuring this one out.
After 4 years Google solved the problem just calling setRetainInstance(true) in Activity onCreate. It will preserve your activity instance during device rotation. I have also a simple solution for older Android.
you should call all activity actions using activity handler. So if you are in some thread you should create a Runnable and posted using Activitie's Handler. Otherwise your app will crash sometimes with fatal exception.
This is my solution: https://github.com/Gotchamoh/Android-AsyncTask-ProgressDialog
Basically the steps are:
I use onSaveInstanceState to save the task if it is still
processing.
In onCreate I get the task if it was saved.
In onPause I discard the ProgressDialog if it is shown.
In onResume I show the ProgressDialog if the task is still
processing.

Categories

Resources