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();
}
Related
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 following tutes from codelearn, and trying create an AsyncTask which generates tweets and executes another AsyncTask to write to a cache file.
I have Thread.sleep, so the UI on first load waits until the Tweets are written to cache file. First I execute AysncTask new AsyncWriteTweets(this.parent).execute(tweets); then sleep for 10 secs.
But in logcat I can see that AsyncWriteTweets also gets executed after 10 sec sleep. Hence onPostExecute gets executed before the tweets are written to the cache file, giving a blank screen.
public class AsyncFetchTweets extends AsyncTask<Void, Void, Void> {
private TweetListActivity parent;
ArrayList<Tweet> tweets = new ArrayList<Tweet>();
ArrayList[] temp;
public AsyncFetchTweets(TweetListActivity parent){
this.parent = parent;
}
#Override
protected Void doInBackground(Void... params) {
int result = 0;
Log.d("ASync", "Calling asycn");
for (int i=0;i<4;i++){
Tweet tweet = new Tweet();
tweet.setTitle("Title Async Very New" + i);
tweet.setBody("Body text for tweet no " + i);
tweets.add(tweet);
}
new AsyncWriteTweets(this.parent).execute(tweets);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void result){
Log.d("Async", "on Post execute");
this.parent.renderTweets();
}
}
PS: My assumption is AsyncTask should create a new thread, hence
Thread.sleep in parent should not stop child. If it is otherwise
please advise how can I overcome this issue.
This:
new AsyncWriteTweets(this.parent).execute(tweets);
is wrong, AsyncTask must be executed on UI thread and not Worker thread. You might use Handler and post runnable to execute it safely.
For reference look into Threading rules:
execute(Params...) must be invoked on the UI thread.
http://developer.android.com/reference/android/os/AsyncTask.html
another part of above link of interest is Order of execution, :
Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
so your first asynctask must end before next one might start, but you migt bring back previous parallel behaviour by using executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR. Still execute must be done on UI thread.
As per documentation on execute() method, a single thread is used for all async tasks. So, if you are sleeping in your async tasks, it will affect other async tasks.
Give executeOnExecutor a try.
This is the flow of my app:
1) The user takes a picture or video
2) The media is saved to internal storage
3) The path is assigned to a custom object
4) The UI is updated to indicate that the user can continue
The UI updates only if the custom object has either an imagepath or a videopath. I've just started using AsyncTask to save to internal storage in a background thread so the app will not hang while saving large files, but I'm having some problems.
What I want to do: Display a ProgressDialog until doInBackground() finishes, then assign the path to my Object, and then continue on the main thread to update the UI.
Right now, the main thread will continue while AsyncTask is still working, and the UI will not update correctly since the path has not yet been assigned to the Object.
I've read about AsyncTask#get(), but I'm not sure how to implement it with the ProgressDialog. I tried, and the main thread didn't seem to wait for the results before continuing.
I'd really appreciate any help. Thank you!
My AsyncTask:
private class SaveMediaTask extends AsyncTask<Integer, Void, String>
{
private ProgressDialog progressDialog;
private int mediaType;
public SaveMediaTask()
{
progressDialog = new ProgressDialog(getActivity(), ProgressDialog.THEME_HOLO_LIGHT);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
this.progressDialog.setTitle("Processing");
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
this.progressDialog.show();
}
protected String doInBackground(Integer... mediaType)
{
//save to internal storage and return the path
return path;
}
protected void onPostExecute(String path)
{
//by the time this runs, the UI has already tried to update itself on the main thread,
//and found that myObject does not yet have a path. Once this runs, it is too late.
myObject.setPath(path);
if (progressDialog.isShowing())
{
progressDialog.dismiss();
}
}
}
How I call it, immediately after the user leaves the camera:
new SaveMediaTask().execute(MEDIA_TYPE_IMAGE);
//WAIT HERE AND DISPLAY PROGRESSDIALOG UNTIL TASK IS DONE
//update UI
Your onPostExecute should notify your activity, that it can continue. So basically:
// Start the task from your activity
new SaveMediaTask().execute(MEDIA_TYPE_IMAGE);
// Method that will be called when task is completed
public void taskComplete() {
// update UI
}
...
protected void onPostExecute(String path) {
myObject.setPath(path);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
((YourActivity)getActivity()).taskComplete();
}
the main thread didn't seem to wait for the results before
continuing.
the main thread wouldn't wait. This isn't how AsyncTask work. AsyncTask runs in background along with your main thread.
then continue on the main thread to update the UI.
You don't need to continue on the main thread to update the UI once AsyncTask task is done, you could simply execute that post doInBackground task in onPostExecute() after dismissing the progressDialog, i.e progressDialog.dismiss(); because onPostExecute runs in the UI thread.
Also, the good way is to start progressDialog inside onPreExecute() method and dismiss it in onPostExecute without checking if the progessDialog is still showing or not because onPostExecute() would only run if the doInBackground() method is finished doing its job.
What I want to do: Display a ProgressDialog until doInBackground()
finishes, then assign the path to my Object, and then continue on the
main thread to update the UI.
Start ProgressDialog in onPreExecute,
Assign the path to your object in doInBackground
Dismiss ProgressDialog in onPostExecute,
Continue your main thread work in onPostExecute since it runs in UI thread.
You can also update your UI thread while doInBackground is still running by invoking publishProgress(). Each call to this method will trigger the execution of onProgressUpdate() on the UI thread.
Tip: Its a good idea to dismiss progressDialog inside onCancelled() method beside dismissing it in onPostExecute() in case if you ever cancel your task inside doInBackground
You can move your code marked with //update UI to the end of your onPostExecute method. onPostExecute is always called on UI thread and is a good place to update UI to reflect the AsyncTask work results.
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();
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.