#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.
Related
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 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.
I am sorry for my bad english skills. I'm new to programming/stackoverflow and try to create a little android quiz app. This app has to connect to a php server and login/getquestion...
The simplest example is the login. The user has to type in his data and then i have to connect.
To provide that the Gui doesnt freeze i have to use asynchronous tasks.
Here the activity's code:
public void login(final String username, final String password) {
final Activity a = this;
FutureTask t = new FutureTask(new Callable() {
public Object call() {
Connection.GetInstance(a).login(username,password);
afterLoginTry(username,password);
return null;
}
});
t.run();
}
This calls a method in another class, which calls another FutureTask which calls an AsyncTask. At the end there is always an public synchronized method such as afterlogintry(). This works but it's a bit slow and i think dirty code.
My main problem is that i don't know how to give results back through different layers of classes and especially to the activity without using hotfixes all the time.
Is there any good explanation or tutorial, which describes how to design such a construct?
Thx for help
The way you can pass AsyncTask results back to other classes, is by declaring callbacks for the task, that will then report the result to a listener. Here is how it works.
First, you must declare an interface in your AsyncTask which contains a method that will send out the result of the task. So in my example task below, my result is a String. The String gets passed to onPostExecute() when the task finishes its work. I then call my callback method on a registered listener, and pass that return value on to whoever is listening for it. You register a listener by passing in an instance of your callbacks from whichever class is creating the task.
public class MyTask extends AsyncTask<String, Void, String> {
MyTaskCallback listener;
public MyTask(MyTaskCallback listener) {
this.listener = listener;
}
protected String doInBackground(String... params) {
String input = params[0];
//do work
input += "did some work on this String";
return input;
}
//When the thread finishes its work, this gets
//called on the main UI thread
protected void onPostExecute(String result) {
listener.onResultReceived(result);
}
public interface MyTaskCallback {
void onResultReceived(String result);
}
}
So next we need to register a listener for these callbacks, so when the result comes in from the task, it will get reported directly to our class. So let's say we have a simple Activity. The way we register the callbacks is to use the implements keyword on our class declaration, and then to actually implement the callback method in the class itself. We then create our task, and we pass in this which is our Activity that implements the callbacks. A simple example Activity that does this looks like this:
public class TaskActivity extends AppCompatActivity implements MyTask.MyTaskCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
//we pass in "this" because our Activity itself
//implements the callbacks below.
MyTask myTask = new MyTask(this);
myTask.execute();
}
//Here we implement our callback method, so the task
//can send its results straight through here
public void onResultReceived(String theResult) {
Log.d("TASK RESULT", "Here is our result String: "+theResult);
}
}
Now, our task has our Activity connected to it, through the callbacks we passed into it. So now when our task gets a result, we can send it directly to our listener, which is our Activity, and the result will come right through to our implemented onResultReceived method.
Callbacks are a great way to pass information around between classes while also keeping everything very separated. Hope this helps!
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.