Suppose I've an AsyncTask like this :
public class MyAsyncTask extends AsyncTask<Void,Void,Boolean>{
#Override
protected Boolean doInBackground(Void... voids){
// Do some stuff
return true;
}
#Override
protected Void onPostExecute(Boolean b){
// Do Some UI Changes
}
}
But instead of calling myAsyncTask().execute() if I call myAsyncTask().execute().get() ,
For example :-
boolean b = new MyAsyncTask().execute.get();
Will the UI changes defined in onPostExecute() method still be applied? In other words does the onPostExecute() method will still be called?
Post execute got called even you called get on async task
Related
I want to show some message and a progress bar while my app initializes.
I need to insert some dictionaries of words into a SQLite database the first time my app is run. To do this I have an AsyncTask which opens my SQLiteOpenHelper and closes it again, just so the database initialization is done once.
private class AsyncDbInit extends AsyncTask<Void, Void, Void> {
private Context context;
private Intent intent;
public AsyncDbInit(Context context, Intent intent){
this.context = context;
this.intent = intent;
}
#Override
protected Void doInBackground(Void... params) {
DatabaseHandler db = new DatabaseHandler(this.context);
db.close();
return null;
}
#Override
protected void onPostExecute(Void param) {
context.startActivity(this.intent);
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... params) {}
}
This AsyncTask is called in my onCreate() method, but I've also tried to run it from onStart() and onResume() without succes.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dispatcher);
... //some code finding the right intent
new AsyncDbInit(this, nextIntent).execute();
}
Somehow this last line, which calls the AsyncTask, stops my UI from showing up; the screen just stays blank until the AsyncTask is completed and the new activity is started.
When I comment that line out, the UI shows up just fine.
The only thing I can come up with is that the SQLiteOpenHelper somehow blocks the UiThread, but I couldn't find anything about that either.
In the AsyncTask we have some methods. Just like in doInBackground() we do the things we wants to be done in the background and there are two methods also whch are onPreExecute() and onPostExecute(). Create and progress dialog and show the dialog in onPreExecute() method and dismiss it in onPostExecute() method.
Try using AsynTask.executeOnExecutor() with the thread pool executor. If this works, it means something involved with loading your UI is also using an AsyncTask. AsyncTasks by default run sequentially on a single work thread and this can introduce contention. This serial execution is often what you want, but not always.
Does you UI use any libraries to load strings or other content? Can you provide your layout XML?
I am calling Asynctask and after complition of doInBackground(String... arg0) i want to call onResume() in onPostExecute() Method.
You should not call explicitly activity lifecycle methods, they usually call base class versions - ie. super.onResume(), so you might mess with activity state. Instead move related code from onResume to some outer function, and call this function instead in your onPostExecute.
Afte AsyncTask Complete
put this line in onPostExecute()
notifyDataSetChanged();
This Will call onResume() Automaticly
or if this is not Work then call Dialog box.
when Dialog box open Activity gosein onPause()
and when DialogBox is close it will call onResume()
this will work
Simply call Activity.this.onResume(); on your postexecution method
1.First of you need to take reference of your Activity say MainActivity in your asynkTask class by doing this.
MainActivity activity=(MainActivity)context.
context is the variable that you pass during calling the asynktask class from your activity.
2.now you can call easily by doing this.
activity.onResume().
Why do you need to do that?
if your async task is a nested class just call a method directly.
public MainActivity extends Activity{
//all the usual functionalities
public void methodAfterAsyncTask(){
//do stuff here
}
private CustomAsyncTask extends AsyncTask<Void,Void,Void>{
#Override
public onPostExecute(){
super.onPostExecute();
methodAfterAsyncTask();
}
}
}
If you are a strong believer of OOP and like clean code :)..I use this method
MainActivity .java
public MainActivity extends Activity{
//all the usual functionalities
public void onResume(){
super.onResume();
new CustomAsyncTask(new AsyncListener(){
public void postTaskMethod(){
//do stuff here
}
}).execute();
}
}
AsyncListener.java
public interface AsyncListener{
void postTaskMethod();
}
CustomAsyncTask.java
publicCustomAsyncTask extends AsyncTask<Void,Void,Void>{
private AsyncListener listener;
public CustomAsyncTask(AsyncListener listener){
this.listener=listener;
}
#Override
public onPostExecute(){
super.onPostExecute();
if(null!=listener)
listener.postTaskMethod();
}
}
Im just wondering what would be the best and possibly easiest way to do this. I have two activites LoginAcitivty and Main Activity.
Ive coded an AsyncTask in my MainActivity as an inner class which sends updates to a web service. When i click the logout button of the MainActivity this returns the app to the Login Activity. Is it possible to still run the ASyncTask even though there is a different activity running or is there another way to do something like this?
Any suggestions would be greatly appreciated
Thanks
The Asynctask is tied to the "Entity" that created it, in your case it would be the MainActivity, so it will not survive the destroy of your activity (I trust you call the finis() method of the main activity once the user logs out)
What you can do is use a service that runs in background and use the async task to poll your server:
The service shall look like this:
public class PollService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
public void onStart(Intent intent, int startId) {
(new PollAsyncTask(this)).execute();
}
//callback used to retrieve the result from the asynctask
void callBack(String result) {
//here is your logic, taking the result back from the async task
//eventually re-run the asynctask
(new PollAsyncTask(this)).execute();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
The AsyncTask shall look like this:
private class PollAsyncTask extends AsyncTask<String, Void, String> {
private PollService caller;
PollAsyncTask(PollService caller) {
this.caller = caller;
}
#Override
protected String doInBackground(String... params) {
//do your polling here and return something meaningful to the service,
return SOMETHING_REFERRING_TO_THE_1_OF_3;
}
#Override
protected void onPostExecute(String result) {
//Give the result back to the caller:
this.caller.callBack(result);
}
#Override
protected void onPreExecute() {//nothing special here}
#Override
protected void onProgressUpdate(Void... values) {//nothing special here}
}
That way your async task will poll your server whatever activity is currently in foreground.
The service shall be started by your first activity when it is run the first time (i.e. in the onCreate method):
#Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState==null) {//only the first time
Intent serviceIntent = new Intent();
serviceIntent.setAction("com.yourcompany....PollService");
startService(serviceIntent);
}
}
Hope this helps.
For what I understand, you have an inner Class in your MainActivity.
So just make your AsyncTask in a separate Class and you can call it from both Activites.
Like: new YourAsyncTask().execute();
Greetings.
I have two AsyncTasks that I am using, one is called up after a dialog returns in the FragmentActivity and there is code after the .execute I call. The other .execute is called just in an if...else. The one called after another dialog returns, does what it is supposed to, it executes, on post execute it pops back the activity to the previous one and everything works.
The other the onPostExecute is never called. I did a break point in the doInBackground which executes and returns the null, just like the other one does but the onPostExecute never happens, is there some issue with having too many AsyncTasks in one FragementActivity, or too many calls to execute? I am stuck and hoping its something stupid I am just not seeing, so I am posting the code but I really cannot figure out why the onPostExecute never gets called in the AddEventWorker but does in the AddEventFromDialogWorker. The way I test the application it does so happen the AddEventFromDialogWorker gets called, works, and then anything to the AddEventWorker does not work (does do the doInBackground but not the onPostExecute).
Any ideas or avenues for me to try?
private class AddEventWorker extends AsyncTask<Void, Void, Void>{
protected void onPostExecute() {
getFragmentManager().popBackStack();
}
#Override
protected Void doInBackground(Void... params) {
mGoogleApi.addEvent(mSession, allGoogleAccounts.get(0).getGoogleCalendarName());
return null;
}
}
private class AddEventFromDialogWorker extends AsyncTask<String, Void, Void>{
protected void onPostExecute() {
Toast.makeText(mContext, "Event added to google calendar!", Toast.LENGTH_SHORT);
getFragmentManager().popBackStack();
}
#Override
protected Void doInBackground(String... params) {
mGoogleApi.addEvent(mSession, params[0]);
return null;
}
}
Your onPostExecute() method is never invoked because you are not overriding the base class' onPostExecute() method. The signature should be protected void onPostExecute(Void result). If you used #Override the compiler would have told you about this issue :)
So I'm an iOS developer learning android, and I'm having a difficult time understanding some things. Right now I have a datamanager class. In that class it has an AsyncTask to update the data. OnPreExecute I pop an activity to show it is updating. I understand I could use extras to pass initial information to the UpdateActivity. My problem is I'm not sure how to send new information in OnProgressUpdate. Here is my code widdled down:
private class myTask extends AsyncTask<Integer,String,Void>{
#Override
protected void onCancelled() {
super.onCancelled();
isUpdating = false;
}
#Override
protected Void doInBackground(Integer... params) {
//My BG Code
}
#Override
protected void onPostExecute(Void result) {
// TODO Remove updating view
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Intent myIntent = new Intent(mContext,UpdateActivity.class);
mContext.startActivity(myIntent);
}
}
AsyncTask is designed to work best when nested in an Activity class.
What makes AsyncTask 'special' is that it isn't just a worker thread - instead it combines a worker thread which processes the code in doInBackground(...) with methods which run on the Activity's UI thread - onProgressUpdate(...) and onPostExecute(...) being the most commonly used.
By periodically calling updateProgress(...) from doInBackground(...), the onProgressUpdate(...) method is called allowing it to manipulate the Activity's UI elements (progress bar, text to show name of file being downloaded, etc etc).
In short, rather than firing your 'update' Activity from an AsyncTask, your update Activity itself should have a nested AsyncTask which it uses to process the update and publish progress to the UI.
You have two options:
1) Pass an instance of activity to your AsyncTask constructor in order to invoke some method on it:
new MyTask(this).execute();
So, you can do:
public MyTask (Activity activity) {
this.activity = activity;
}
public void onPostExecute(...) {
activity.someMethod();
}
2) Pass a Handler instance and send message from onPostExecute() to the activity.