Cannot close Activity from AlertDialog called in PostExecute - android

I have a couple of Activities both of which send files up to the internet.
I would like to put the posting procedure into a separate class file so that the same procedure is called for each activity.
I pass the context of the calling activity to the main AsyncTask method which, in turn calls preExecute, doInbackground, Postexecute.
I have an AlertDialog, built using the context passed to the AsyncTask, in the postexecute method that shows the message returned by the server, with an OnClickListener to dismiss it. When the button is clicked the alertdialog is closed but the underlying activity screen is not.
I've tried several different combinations of finish() including:-
dialog.cancel();
finish();
and
dialog.cancel();
MyActivity ma = new MyActivity();
ma.this.finish();
nothing, though, will close the Activity.
What am I doing wrong and what do I need to do to get it to close?
So far the only way I can get it to work is to embed the exact same code in both Activities which seems to me to be both inefficient and susceptible to error.
Any help would be very welcome.

I pass the context of the calling activity to the main AsyncTask
instead of only passing context of Activity you will need to pass Activity instance to class in which extending AsyncTask class because finish method is from Activity class instead of from Context .so try it as:
public class Networkasynctask extends AsyncTask<...>{
Activity activity;
Context context;
public Networkasynctask(Context context,Activity activity,...){
this.activity=activity;
.....
}
....
}
and pass Activity instance as from Activity:
Networkasynctask networktaskobj=new Networkasynctask(this);
now use Networkasynctask.this.activity.finish() for closing Activity from non Activity class

Related

What context to use in Multi activity android app?

I'm badly confused and hope to get your help understanding this concept.
I have an app with 3 activities, splash, login and main and the main activity is a multi fragment drawer activity that uses sqlite.
In my fragments i need to use context many places. I used to have a static context in my main activity defined and passed that around but in another questions someone suggested not to use static context to avoid leaks and i took the advice.
I had to change a few things and got things working. I use getapplicationcontext() but now my application now consistently crashes. The crashes are more prominent when the app is put in background.
My question is, which activity's context should i be using to start with? Splash? Login or main? How would you get access to the context in resume?
Thanks
If you are in A fragment you can use getActivity() to access its container activity context.
If you are try to access activity context from an adapter class or dialog, you must pass the activity context to the constructor of the adapter class or dialog
If you are in an activity you can use this or yourActivity.this as per the situation.
For example
1)If you want to access activity context from onResume() or onCreate() you can simply use this.
2)If you are try to access activity context from an inner class like retrofit call then you must use yourActivity.this for activiy context

Stop asynctask from other activity

I creating an app using asynctask to download file from server. It has several activities. I start one asynctask from activity A and I want stop it from activity B. How can I archieve it ???
It is possible to call a previous activity's public methods by using typecasting of the getParentActivity() method on your activity B :
((PreviousActivity)getParentActivity()).somePublicMethod();
This only works if you opened Activity B from Activity A. If you want to be able to call that method from all activities, try creating a static class and save an instance of Activity A. This way, wherever you are on the app, the method can be called. Be also wary of null values when doing this.
This is the sample of the static class.
public static class Constants{
public static ActivityA activityAInstance;
}
When you open ActivityA (onCreate method) save it's instance:
Constants.activityAInstance = ActivityA.this;
This part saves the instance of ActivityA to your static class. So whereEver you are on the app, you can access that instance and call it's public methods:
e.g. the app is on ActivityZ all you have to do is import that static class and call ActivityA instance:
Constants.activityAInstance.somePublicMethodToStopTheAsyncTask();
In my opinion , you can set a boolean flag in activity A ,and when you run the asynctask , you should check this flag ever time,if you want to stop ,you just change the flag , so you could change this flag in activity B to stop the asynctask.
you should try this.
I think you can use LocalBroadcastIntent to send a message from activity B to activity A. In method receiver of A, you can call Asynctask.cancel(true). And you should place if(isCanceled()){
break;
}
in your asynctask's loop to stop the task when you call Asynctask.cancel(true).

Pass Variables from AsyncTask back to calling to Activity

I am new to Android Development and have a question (will probably show my newbie status). I am calling an asynchtask from a custom activity. Once the asynch task is completed onPostExecute I would like to call back into my activity and set a pojo (Map()). I know that onPostExecute seems to run on the UI thread but I am not sure how to get visibility into the calling Activity.
The goal is to be able to have some variables set in my activity and ideally the webservice call will already be completed.
Thanks,
Craig
If the AsyncTask is a subclass of the activity, it has access to all public, protected, and private variables of the superclass. If its not, you need to write a public function in the Activity class to set the variables, and call it from the AsyncTask. That will probably require you to pass the activity to the AsyncTask via the constructor and save it in a member variable of the task.

Passing Activity object to static class

I have different Activities where the catch{} block mostly should do the same, eg. show a Toast message, finish() the app, or something else. So I made one static class to handle them. It works till now, but I want to know that it's save.
To finish an Activity I have to call finish() which is in the Activity class, so I have to pass it.
I made a static function like this:
public static void handleException(Exception e, Context c, Activity a) {
// handle the exception, for example if there is an authorisation error:
a.finish();
}
In a catch{} block I do the following: (in this case Activity LoginActivity)
ExceptionHandler.handleException(e, _context, (Activity) LoginActivity.this);
Is this appropriate? Or does this cause memory leaks?
If you dont save any link to Context or Activity there will not be any memory leaks or problems with GC.

Getting Reference to Calling Activity from AsyncTask (NOT as an inner class)

Is it at all possible, from within an AsyncTask that is NOT an inner class of the calling Activity class, to get a reference to the instance of Activity that initiated execution of the AsyncTask?
I am aware of this thread, however it doesn't exactly address how to reference the calling Activity. Some suggest passing a reference to the Activity as a parameter to the AsyncTask constructor, however, it's reported that doing so will always result in a NullPointerException.
So, I'm at a loss. My AsyncTask provides robust functionality, and I don't want to have to duplicate it as an inner class in every Activity that wants to use it. There must be an elegant solution.
The "elegant solution" is to actually try passing it as a parameter (to the constructor or execute()) and see if it works, rather than assuming the person who asked that previous question (then answered his own question twice) knows what he is doing. I can think of nothing intrinsic to AsyncTask that would cause Activity to be a bad constructor parameter and every other object be just fine.
Now, I haven't passed an Activity (or other Context) as a parameter to an AsyncTask, because my AsyncTasks are always private inner classes. In fact, the fact that you want a public AsyncTask to me is a code smell, suggesting these tasks should be mediated by a Service or some other control point. But, that's just me.
UPDATE
A better answer for handling this pattern can be found here: Background task, progress dialog, orientation change - is there any 100% working solution?
My AsyncTasks always live in a separate package while still bound to a particular type of Activity. They accept it's instance in constructor and store in a local variable.
Try thinking in terms of creating an abstract Activity class that encapsulates AsyncTask-related stuff and is extended by other activities.
Like so:
public abstract RemoteListActivity<T> extends ListActivity{
// calls AsyncTask, shows spinning progress dialog, etc
protected abstract T someConcreteMethod();
}
public final class CustomerListActivity extends RemoteListActivity<Customer>{
protected final Customer someConcreteMethod();
}
Alternatively, if things don't fit in a single hierarchy, have an interface:
interface LazyLoadable {
void setLoadingState();
void setDefaultState();
}
public class MyActivity extends Activity implements LazyLoadable{
}
public final class AsyncTask extends AsyncTask<Void, Void, Void>{
private final LazyLoadable lazyLoadable;
public MyAsyncTask(Context ctx, LazyLoadable lazyLoadable){
super(ctx);
this.lazyLoadable = lazyLoadable;
}
}

Categories

Resources