For some reason my onPostExecute() is not called after my AsyncTask finishes.
My class decleration:
public class setWallpaperForeground extends AsyncTask<String, Integer, Boolean>
My onPostExecute():
protected void onPostExecute(Boolean result)
Everything works fine, my doInBackground() completes successfully and returns a Boolean but then it just finishes.
Thanks
Did you start the task with execute() method? The onPostExecute wouldn't run if you just invoke the doInBackground.
Did you create your AsyncTask on the UI thread? Also add an #Override annotaiton on your onPostExecute() method to make sure you declared it correctly.
Found/Made another nasty mistake:
If your params of onPostExecute(Param param) don't match the one you defined with extends AsyncTask<...,...,Param> and you didn't use the #Override annotation, it will never be executed and you don't get a warning from Eclipse.
Note to myself:
Just always use the #Override annotation and Eclipse will help you.
Another easy way to avoid all named mistakes:
in Eclipse: Right-click in code > Source > Override/Implement Methods
After having the same problem and none of these answers helped me, I found out that my UI thread was blocked (I used a CountDownLatch.await()) and therefore the onPostExecute() method that is supposed to be called by the UI thread was never called.
Made another nasty mistake that can result in this same error. When defining the AsyncTask and calling it, I was not calling execute but was calling doInBackground
new AsyncTask<String,Void,Void>() {
....
}.doInBackground("parameter");
rather than
new AsyncTask<String,Void,Void>() {
....
}.execute("parameter");
I have faced the same problem. None of the above solutions worked for me. Then i figured out the problem maybe it helps someone else .
In UI thread i call the following codes:
public class XActivity ...{
onCreate(){
....
new SaveDrawingAsync(this).execute();
while(true)
{
if(MandalaActivity.saveOperationInProgress){
continue;
}
super.onBackPressed();
break;
}
...
}
}
My AsyncTask class definition :
public class SaveAsync extends AsyncTask<Object, Void, Void> {
#Override
public Void doInBackground(Object... params) {
saveThem(); // long running operation
return null;
}
#Override
public void onPostExecute(Void param) {
XActivity.saveOperationInProgress = false;
}
#Override
public void onPreExecute() {
XActivity.saveOperationInProgress = true;
}
}
in the above code onPostExecute is not called. It is because of an infinite loop after asynctask execution .
asynctask and inifinite loop both waits eachother to finish. Thus the code stucks!
The solution is changing the design!
I had the same behaviour, and the cause was that I have been posting a lot of messages as a progress inside doInBackground with following code:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// .. some UI updates
}
});
this must have overloaded main thrad message queue, and caused long delay before onPostExecute would get called. The solution was to post only once every second.
For me it was user error. I was ending the AsyncTask by invoking cancel(true) on it and not reading the documentation closely enough to know that onPostExecute is not called in this case, onCancelled is.
Related
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
asyntask.execute();
}
I'm reading data from some API. Is it possible to call doInBackground() from onPostExecute?
I want do it recursively like (network task and update in UI ) for 5 times. Thanks in advance.
Starting the AsyncTask again from inside onPostExecute is a horrible idea. As you want to do it recursively like 5 times for network calls along with UI update, I would like to suggest you to keep an interface to keep track of the AsyncTask call.
So here's an example about how you can achieve the behaviour. You may create an interface like this.
public interface MyResponseListener {
void myResponseReceiver(String result);
}
Now you declare the interface in your AsyncTask class too. So your AsyncTask may look like this.
public class YourAsyncTask extends AsyncTask<Void, Void, String> {
// Declare an interface
public MyResponseListener myResponse;
// Now in your onPostExecute
#Override
protected void onPostExecute(final String result) {
// Send something back to the calling Activity like this to let it know the AsyncTask has finished.
myResponse.myResponseReceiver(result);
}
}
Now you need to implement the interface you've created already in your Activity like this. You need to pass the reference of the interface to the AsyncTask you're starting from your Activity
public class MainActivity extends Activity implements MyResponseListener {
// Your onCreate and other function goes here
// Declare an AsyncTask variable first
private YourAsyncTask mYourAsyncTask;
// Here's a function to start the AsyncTask
private startAsyncTask(){
mYourAsyncTask.myResponse = this;
// Now start the AsyncTask
mYourAsyncTask.execute();
}
// You need to implement the function of your interface
#Override
public void myResponseReceiver(String result) {
if(!result.equals("5")) {
// You need to keep track here how many times the AsyncTask has been executed.
startAsyncTask();
}
}
}
doInBackground() is called before calling onPostExecute.
Since you cannot perform network tasks on the UI thread, an AsyncTask is created.
The AsyncTask executes in the background, performing the network task on the worker thread. Then after the background task is completed, onPostExecute() is called that makes the UI changes on the UI thread.
This should help : https://developer.android.com/reference/android/os/AsyncTask.html
https://developer.android.com/training/basics/network-ops/index.html
The AsyncTask class is used to do some work in background and publish the results to the MainThread so it's generally not possible because the work that's being done in the worker thread may not be doable in MainThread, (like the NetworkOnMainThreadException when you do networking in MainThread).
I suggest you to make an array of your jobs and call the execute() method of your subclass of AsyncTask and it will serialize the jobs to be done in a worker thread.
I am using AsyncTask so that the function I want executes immediately and does not wait till the end to be executed..
but for some reason I don't why it executes in at the end of all process!
I looked at other solutions and found that Thread should be executed at the end but for AsyncTask it should be executed whenever it is called..
here is my code
private void LogMeIn()
{
string CheckValue;
// Here I call the AsyncTask
new GCM().execute(null,null,null);
//gcmRegID is a public variable and should has GCM value assigned to it by now, but I it is empty as GCM() has not been executed yet
//This is always return empty string
CheckValue = gcmRegID;
}
This is the AsyncTask that wait till the end to be executed
//This is the AsyncTask
private class GCM extends AsyncTask<String, String, String> {
private String resp;
private Context context;
#Override
protected String doInBackground(String... params) {
GCMHelper gcmRegistrationHelper = new GCMHelper (
getApplicationContext());
try {
gcmRegID = gcmRegistrationHelper.GCMRegister("123456789");
} catch (Exception e) {
e.printStackTrace();
}
return gcmRegID;
}
}
I tried to put the call for GCMRegister in onPreExecute but i get an error that it has to be in the main thread
it is like i am going in circles....
the call has to be in the main thread and the main thread will be executed at the end of the function...
it is like no way to get the GCM code in the middle!!!!
How can I make this AsyncTask executes when it called??
Thanks
Without seeing more of your code it's hard for me to tell but I would take a look at where you are calling LogMeIn(). Because your AsyncTask and call to execute are nested in the LogMeIn() function, it won't be called until LogMeIn() is first called.
AsyncTask goes through the following 4 steps in order after calling execute():
onPreExecute()
doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
These can be added to your GCM class and used however you like. Note that you don't call them directly. AsyncTask does it automatically after calling .execute().
Only the tasks specified in doInBackground(Params...) are executed on a background thread. The rest are all done on the UI(or main) thread. I would suggest putting either a toast or a log inside onPreExecute() and in onPostExecute() to debug where/when GCM().execute is actually being called and then to tell you when the background task is complete. This will give you a better idea of what is going on.
Make sure you aren't trying to update the UI in doInBackground().
Would love to help more but we would need to see more of your code.
#Override
public void onPreExecute() {
super.onPreExecute();
Log.d("GCM", "onPreExecute: called");
}
#Override
public void onPostExecute(String resultOfDoInBackground) {
super.onPostExecute(resultOfDoInBackground);
Log.d("GCM", "onPostExecute: called");
}
AsyncTask keeps a queue of tasks and a thread pool,the thread pool execute the tasks one by one,so if you have too more tasks ,you will find it not execute your tasks immediately.
And in one process ,all your AsyncTask share one thread pool.In this case,you should make one task queue by yourself,you can just use HandleThread to execute a timely task.
Try placing your new GCM().execute(null,null,null); in the protected void onCreate(Bundle savedInstanceState) method. this way it will be called once the app is ran. This way you will have your GCM id before you get to the LogMEIn method.
Try this -
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new GCM().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,params);
} else {
new GCM().execute();
}
If I did something like this:
public class MyFragment extends Fragment
{
private GetDataTask mGDT;
//onCreate() and onCreateView() are implied here
public void runTasks()
{
new TaskOne().execute();
new TaskTwo().execute();
new TaskThree().execute();
}
public class GetDataTask extends AsyncTask<Void, Void, Void>
{
#Override
protected Void doInBackground(Void... params)
{
runTasks();
}
}
#Override
public void onResume()
{
super.onResume();
mGDT = new GetDataTask();
mGDT.execute();
}
#Override
public void onDestroy()
{
super.onDestroy();
mGDT.cancel(true);
}
}
Would calling mGDT.cancel(true) in onDestroy() end the individual AsyncTasks running in runTasks()? What is the best way to achieve something like this? I have multiple bots that will be gathering data from the web and I want each one on its own thread and I need to be able to cancel all of them if the fragment or activity is destroyed. I'm new to Android programming and multithreading so I'm not familiar with the best ways to do this type of multithreading.
That's complicated.cancel() interrupts the thread that's running (the thread that will run doInBackgroundImpl()). If the outer task's doInBackgroundImpl() hasn't run yet, it won't run. However, if it's already run or in the middle of running, it's going to run unless you explicitly look for the interrupted flag,
#Override
protected Void doInBackground(Void... params)
{
if (!Thread.isInterrupted()) {
runTasks();
}
}
And of course if the code execution of the thread has already passed the conditional interrupted check, it's going to call runTasks().
Now, if runTasks() does execute(), canceling the outer task won't effect the execution of the inner tasks. Once they are executed, they are placed on AsyncTask's executor queue and will be executed when previous task is completed (or right away if the queue is empty).
Takeaways,
1) Each executed task is independent. There's no notion of a subthread or anything like that. You have to explicitly cancel each task. The fact that one task is started by another task has no bearing on the semantics of cancel().
2) You simply can't stop a thread cold. It's why Thread.stop() is deprecated since Java 1.2 or something. All you can do is mark it interrupted, then either hope the code you use in the thread respects isInterrupted(), or write your own code to respect it.
In your case, if your goal is to cancel all subtasks when the parent task is canceled, you can do something like,
#Override
public void cancel(boolean interrupt) {
super.cancel(interrupt);
task1.cancel(interrupt);
task2.cancel(interrupt);
...
}
I am writing a very simple unit test case for my Android project, the test case simplely execute a AsyncTask which does network operation in background. I am extending AndroidTestCase class for my test case:
public class MyTest extends AndroidTestCase{
//use CountDownLatch to perform wait-notify behavior
private CountDownLatch signal;
#Override
public void setUp() throws Exception{
super.setUp();
//I use CountDownLatch to perform wait-notify behaviour
signal = new CountDownLatch(1);
}
#Override
public void runTest() throws Exception{
String params = "some params";
//MyAsyncTask does the networking tasks
new MyAsyncTask().execute(params);
//wait until MyAsyncTask is done
try {
signal.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class MyAsyncTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
//Do networking task e.g. access a remote database
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
//this never get called when run this test case, why?
Log.i("Debug","post execute");
signal.countDown();
}
}
}
As you see above, I am using CountDownLatch to perform wait-notify behavior.
After MyAsicTask starts, I invoke signal.await() to wait for MyAsyncTask to finish.
In onPostExecute() callback of MyAsyncTask, I call signal.countDown() to notify that the task is done.
But when I run this test case, the onPostExecute is never called, why & how to fix it?
========Update==========
After I added Thread.sleep(30*1000) as the last line in runTest(), I can see more logs from network operations. It proves that the teardown() is invoked before my network operation finished. I did nothing in tearDown(), android test framework. invokes it automatically.
Seems my wait-notify by using CountDownLatch is not working... Why?
Since I had the same problem... here's what solvede it for me.
Instead of letting the class extend AndroidTestCase I let it extend InstrumentationTestCase.
Then i start the asyncTask like this:
runTestOnUiThread(new Runnable()
{
#Override
public void run()
{
startAsyncTask();
}
});
Be sure that your doInBackground method is not the reason this problem. Try this sample task. And share the log result please.
private class MyAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.i("Debug", "onPreExecute");
}
#Override
protected String doInBackground(String... params) {
Log.i("Debug", "doInBackground");
return "operation finished";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i("Debug", "onPostExecute");
signal.countDown();
}
#Override
protected void onCancelled() {
super.onCancelled();
Log.i("Debug", "onCancelled");
}
}
Edit: I wondered that there may be a problem while working with AndroidTestCases and AsyncTasks. I just copied your code to my project and tested it with an AsyncTask(see my task above). On every launch after doInBackground, onPostExecute method is called successfully. I simulated a long running task with sleep 2 minutes, and that also entered to onPostExecute method. And tearDown method invoked after onPostExecute.
So, your problem here is probably a loop inside your doInBackground method. Or it is cancelled somehow and task's onCancelled method invoked.
I think your network operation is very time consuming process so it takes so long time that why its can not called onPostExecute() method.
The onPostExecute() is supposed to be run in the caller thread of execute(). If that thread becomes suspended by calling something like signal.await(), the onPostExecute() won't be able to run. So you cannot have signal.await() after calling execute().
I am new to java and have a swing task question.
Can I add a listener to a currently running task? For instance if something happens in doInBackGround I want to add a listener for finished and display a dialog. I have tried but the compiler doesnt like me. :)
Something like.
private class MyTask extends Task<Void, Void>{
#Override
public void doInBackground(){
if(foo == foo){
this.addTaskListener(new TaskListener() {
public void taskFinsished(){}...
});
}
}
}
Thanks
Task is not a listener-oriented component. You need to override one or more of it's methods to get the results. All of these methods will execute on the EDT.
cancelled() - The cancel() method was called to terminate the task.
succeeded(T result) - The Task completed, and result holds the return value from doInBackground().
interrupted(InterruptedException e) - interrupt was called on the Thread executing the Task.
failed(Throwable cause) - The doInBackground threw an exception.
finished() - The Task has finished (in some fashion). Think of this as the functional equivalent of finally for Tasks.