Android: AsyncTask - onPostExecute never gets called - java

I have been browsing about this I am not finding the answer that suits my problem. But i would like on execute onPostExecute but it never gets called.
I send in a timestamp, unixtime, to the server and I get a list in return (ArrayList). Then I want to work with that list in onPostExecute. I do get the list though.
I send in Long
I want to work with that list, I think.
I want to return that list
Thats why I do 'Long, ArrayList, ArrayList'
Could use a little help, thanks!
private class getMealsByDayConnection extends AsyncTask<Long, ArrayList<CalanderMeal>, ArrayList<CalanderMeal>> {
protected ArrayList<CalanderMeal> doInBackground(Long... params) {
CalendarService service = CalendarServiceFactory.getCalanderService();
try {
return service.getMealsByDay(params[0]);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(ArrayList<CalanderMeal> result){
CalendarAdapter adapter = null;
adapter.notifyDataSetChanged();
}
}

According to the documentation, the method will not be called if the task is cancelled. So perhaps your task is being cancelled since an empty list is returned? Or the onPostExecute(result) doesn't work because result is an empty list? You might be able to catch this by overriding onCancel().
Btw, you did call the async task from within the main UI thread and start the task with the getMealsByDayConnection.execute() method, right?

i think you are calling asyncTask with
getMealsByDayConnection.doInBackground(params);
if you are executing like this , task will execute in main thread and the doInBackground() function alone will execute.
you should execute asynctask like this,
getMealsByDayConnection.execute();

Related

AsyncTask executes at the end of the function

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();
}

Wait async tasks in android

i am newbie on android development and i would like to ask how to wait some async tasks that already running. Also when i am trying to sleep the main Thread many of them are suspended by the system. When i use an arraylist to add them and then call to each of them get() many of them never finish on time. Please give me a code example because i searching it over of three days...
Thx!!
for(){
async...
async.execute();
arraylist.add(async);
}
...
for(arraylist.size){
arraylist.get().get();
}
I will try to answer your question here but the question is not clear.
If you want to check whether there is an AsyncTask completed or not in an arraylist, we can use getStatus call that return us a status, and one of the status, luckily, is FINISHED, so you can check your status of any given AsyncTask.
If you want to sleep until one of the AsyncTask is finished, then the best approach probably involves doing something in onPostExecute. When you override it, you can do something to notify the main thread. One of the ways you can do this is here:
public interface Callback {
public void callBack(int id);
}
public class MainActivity implements Callback {
private void function() {
//do your thing
AsyncTask task0 = new MyAsyncTask(this, 0); //implement your own asynctask here,
//with one of the parameters this activity so that you can get a callback.
//Also, optionally give in the id so that you know what index of asynctask is finished first.
//do the same thing for other tasks
task1.execute(params);
}
public void callBack(int id) {
arrayList.get(id).get(); //this is done
}
In your AsyncTask, you simply override the onPostExecute to something like this
protected void onPostExecute (Result result) {
//do your thing
mainActivity.callBack(id);
}
Hope this helps.

Asynctask ArrayList object not passing from doInBackground to onPostExecute

I have an AsyncTask that takes in context (used onPostExecute) and runs doInBackground to return an ArrayList of objects from a server. When I execute this I can see that doInBackground runs fine, however it is not passing the result on to onPostExecute.
After much searching, I have yet to find an answer of how to return an ArrayList of objects in an AsyncTask.
This is the object I'm creating in doInBackground and using onPostExecute:
public class ServerTimeCard {
public String eventNameInput;
Boolean isLocation, isImage, isVoice;
public ServerTimeCard(String eventNameInput, boolean isLocation, boolean isImage, boolean isVoice) {
this.eventNameInput = eventNameInput;
this.isLocation = isLocation;
this.isImage = isImage;
this.isVoice = isVoice;
}
}
I'm executing the AsyncTask with new LoadFriendCards(context).execute(); in onCreate.
Expected Output: doInBackground should return an ArrayList to onPostExecute
Current Output: The ArrayList<ServerTimeCard> in onPostExecute has a size of zero when the same arraylist in doInBackground has a larger size.
The following is the AsyncTask code.
public class LoadFriendCards extends AsyncTask<Void, Void, ArrayList<ServerTimeCard>> {
Context context;
ArrayList<ServerTimeCard> result;
public LoadFriendCards(Context context) {
this.context = context;
}
#Override
protected ArrayList<ServerTimeCard> doInBackground(Void... voids) {
result = new ArrayList<ServerTimeCard>();
// ...a bunch of data retrieval goes on here...
// querying parse for object info
// adding a new object to the local ArrayList for all in db
for (String friend : friendsListNames) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("TestObject");
query.whereEqualTo("accountName", friend+"#gmail.com");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
for (ParseObject cardInfo : objects) {
ServerTimeCard item = new ServerTimeCard(
cardInfo.getString("eventName"),
cardInfo.getBoolean("isImage"),
cardInfo.getBoolean("isImage"),
cardInfo.getBoolean("isVoice"));
result.add(item);
Log.e("New item called: ", String.valueOf(item.eventNameInput));
Log.e("New size of array...", String.valueOf(result.size()));
}
} else {
Log.d("info", "Error: " + e.getMessage());
}
}
});
}
// returning the new ArrayList<ServerTimeCard> to onPostExecute
// PROBLEM: THE SIZE OF THE RESULT IS 0
Log.e("Size of passing array", String.valueOf(result.size()));
return result;
}
#Override
protected void onPostExecute(ArrayList<ServerTimeCard> result) {
// PROBLEM: This returns 0
Log.e("Data list size: ", String.valueOf(result.size()));
// trying to use all objects in the arraylist here but it doesn't work
// due to the size. Something isn't passing correctly.
}
}
Logcat output of Log.e: (which looks like it calls doInBackground, then onPostExecute, then doInBackground again)
E/Size of passing array﹕ 0
E/Data list size:﹕ 0
E/New item called:﹕ yah
E/New size of array...﹕ 1
E/New item called:﹕ lplokolol
E/New size of array...﹕ 2
E/New item called:﹕ It works
E/New size of array...﹕ 3
SOLVED: I originally thought I needed the AsyncTask but I ended up deleting it all and throwing all the code into a method in my Main class. I was running too many things at once in an asynctask and the structure was throwing data all over the place. Lesson learned: keep it simple.
Your issue is that you are using findInBackground for your query. That method is done in a background thread. So you're basically running an async task, within an async task.
doInBackground
findInBackground -> run asynchronously so code execute continues
onPostExecute is called before your query finishes.
The done call back is then called for your query to fill your list
So what you need to do instead is either use findInBackground outside of an AsyncTask (that method is intended to not be used in an AsyncTask) or use the find function.
You're modifying result in an anonymous inner class. Your code there doesn't see the result you think it sees, but rather a closure. This is the root of the problem.
You are starting a background thread (your async task), and here you call query.findInBackground() multiple times which starts MORE background threads. This, however, isn't a problem.
You're getting problems because the AsyncTask is done before all the other threads it started have finished. You only know the other threads are done when each of their FindCallback's done() method is called.
If you want to know the correct size, you need to code it in a way so that you check the size in the last done() method.
You dont have to make doInBackground to return an arraylist which can be used in onPostExecute. Just return "ok" or "error". Declare and create a private arraylist as member of your ask. Then fill it in doInBackground and use it in onPostexecute.
An alternative and simpler way is to declare your doInBackground as List type.
Here is my Example
#Override
protected ArrayList<ServerTimeCard > doInBackground(String... urls) {
// Perform the HTTP request for earthquake data and process the response.
ArrayList<ServerTimeCard > result = QueryUtils.fetchTheData(urls[0]);
return result;
}

How to make a thread return arraylist of objects in java?

I want a thread to return list. I cant use the run method as its return type is void. I am using the thread in a separate private method inside a class under which the caller method of the thread is also there. The caller needs the list from thread result to do some manipulation. here is my thread. Pls help me in understanding how can i return list from this thread.
private List<myObject> fetchmyObjList(final String abc){
new Thread(new Runnable() {
#Override
public void run() {
try {
List<myObject> myObjList = anotherInternalMethod(abc);
} catch (Exception e) {
System.out.println(e);
}
}
}).start();
}
how can i make this thread return myObjList to the caller?? Please help.
You need Callable instead of Runnable.
Here is an how-to-use callable: https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6
Use callable instead of Runnable. The function is capable of returning a value in the form of Futures. You can utilize this to achieve your own purpose.
You can push your data to external object (like object which have fetchmyObjList) using just a method like:
List<myObject> myObjList = anotherInternalMethod(abc);
setFetchedObjects(myObjList);
This is a scenerio when you puts controll to newly created thread. We can call it simplivied observer pattern - outer object is notified by method call when data is available. But remember about thread safety in this scenerio!
Other scenerio is to use Callable<OBJECT YOU WANT TO RETURN> and use a Thread/ExecutorService to start your task. Then (in control in your outer object) you can use Callable .get() to get your result.
You cen use blocking or nonblocking methods to wait for result or to check if result is ready to receive from background task.
Of course in your scenerio, creating a Thread with Callable just to block original thread and wait to task completion to return your objects from method, gives nothing - it would be better to not use threads at all.
If you want to perform background operation, change your method signature to return null + call a "listener" method when data will be ready or return a Callable<List<myObject>> and retreive data from it after some other operations done in pararell.
You need to rethink what you're doing. The new thread will run in parallel with the old one, and may not have an answer ready until the calling thread's got a lot more work done. You could make the calling thread wait, but why not just call 'anotherInternalMethod' from the main thread?
You could do something like this (but don't!):
private void fetchmyObjList(final String abc, final List<myObject>[] retList) {
new Thread(new Runnable() {
#Override
public void run() {
try {
retList = anotherInternalMethod(abc);
} catch (Exception e) {
System.out.println(e);
}
}
}).start();
}
but the passed retList object (a one-element array) will not get set correctly until some unpredictable time in the future.
This can be solved by the Callable interface in place of Runnable, and retrieving the value with a Future object, which also lets you wait until the value has been computed. You can achieve this with an ExecutorService.

onPostExecute not called after completion AsyncTask

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.

Categories