In an Android activity I'm executing an AsyncTask in onCreate method.
Should I declare the handler function of UI buttons inside onPostExecute of AsyncTask or in OnCreate method? Can I create another AsyncTask inside this button onClick handler? Thanks
A little bit of code would be helpful to better answer you. But the call to the constructor or the execute() method can be done in onCreate() but the actual class should be created either in a separate file or as an inner class of your Activity, depending on what you need it for. What you are explaining would probably work but I wouldn't put onClick events in your AsyncTask. If nothing else, for the readability. Also, this may make it more error prone, in my opinion. You might need local variables outside of the AsyncTask for the onClick() so this would reduce scope issues. Calling an AsyncTask from inside an onClick() would generally be fine to do. I hope this makes sense but if you need more clarification feel free to ask
Related
I have an AsyncTask which calls a method of another class(where all the computational logic resides) which performs some background operations. I want to show the status/progress of the operation. I know that we can call publishProgress() in doInBackground() to publish the progress on to the UI thread. But as the logic resides in another class I need to pass the instance of an AsyncTask to call publishProgress() from there.
Is it a proper way? Will it cause any runtime issue or memory leak?
If someone has been through this, please guide me to achieve this in a proper way.
Edit1 : In the AsyncTask I am calling a SOAP web service
It isn't good idea to use AsyncTask at all - it is obsolete. Use rxJava library instead
As I understand in your question, you have a method you call from doInBackground, If that method doesnt save anything outside that method scope (in member or static member or in a member of a static member etc.) than it is rational to say that the execution itself will not leak the AsyncTask and the context that is being referenced from it. But there is more to that, even if the above is the case, you still have so many ways that this AsyncTask would leak.
How i can know when AsynsTask is ready from Activity? I can not write my code in a separate class, because i use ListView, and fill him. How i can do that without Thread.sleep ?
You can use the onPreExecute and onPostExecute methods of AysncTask to update your UI i.e Activity. Because this methods directly run on main thread
Question arising from my first attempt at using an Async object.
I have a main activity in which some TextViews have been created programmatically and added to a LinearLayout. Also a button, when this is clicked, an AsyncTask object is instantiated and results are obtained in the doInBackGround method. How should the result strings be transferred to the TextViews?
a) by calling the SetText methods of these TextViews from the onPostExecute method,
b) using intents and an onActivityResult method in the main activity
c) some other way (a clue would be nice!)
Thanks!
I would go for the AsyncTask option. I'm guessing that as you already have one in place, the obtaining results part that happens when you click the button takes time, so it's good design to have that in the doInBackground method of the AsyncTask.
Then you can call each TextView's setText(...) method in the onPostExecute method in your AsyncTask. Or, it's more suitable, you can update each view as you get the result by using the publishProgress(...) and onProgressUpdate(...) methods (see the AsyncTask documentation) during the background calculations, instead of having to wait until the end.
Just bear in mind that you can only call setText(...) from the onPreExecute, onProgressUpdate and onPostExecute methods, as (at least it seems this way from your explanation) the views have been created on the UI thread, so they can only be modified from that same thread, which those methods run on.
When using an AsyncTask, you can use the doInBackground method for processing, and the onPostExecute to update any UI changes. So, if you need to use an AsyncTask, I'd go for option A.
Make the TextViews private and define them in doInBackground, then you can just call the setText method in onPostExecute or as the last thing in doInBackground, but i would recommend onPostExecute.
I am getting a "CalledFromWrongThreadException" error when I try to update a TextView (via a listener) from an AsyncTask onProgressUpdate.
If I try to update the same TextView from onPostExecute everything works.
I have been testing using code based on
https://github.com/commonsguy/cw-android/tree/master/Service/WeatherAPI
(with a small mod that does an onProgressUpdate in the doInBackgroundMethod, and adds the onProgressUpdate override)
Any suggestion to fixes would be most appreciated.
Are you calling onProgressUpdate() from your code? You shouldn't do it. Use publishProgress() method.
onProgressUpdate doesn't run on UI thread, so you can't access views from this method. If you want to update progress, you should find a way to synchronize your AsyncTask with your activity. A way that I'm using is to create an interface with methods like onBegin, onUpdate and onFinish. You should implement this interface in your main activity class. Then you should have an instance of your activity inside your AsyncTask. In the onProgressUpdate method you just call the onUpdate method in your activity and update the layout. Hope I've explained it clear enough.
Consider this: I've got Activity, in onCreate() I start AsyncTask to load its content. I've followed this sample. Now my problem is: I want to download file in that Activity, using AsyncTask. But I don't know how to make existing AsyncTask do various tasks.
If anyone had the same problem, I would appreciate your help.
Well, I've succeeded to make it call again and again... you have to instantiate your class as a null first (int the Activity).
MyAsyncTask asyncTask = null;
and then put it in a try... catch block:
asyncTask = (MyAsyncTask) new MyAsyncTask().execute(params);
The other thing you're interrested about is the differenc methods you want to run... Well, I wanted to do the same, but I've had no time writing that one, but I've thought about it on the way home from work.
I think your class extending AsyncTask should look like this:
class MyAsyncTask extends AsyncTask<Object, Object, Object> { }
create some variables or ArrayLists in your AsyncTask, and do the decision on the overriden onPreExecute() method where you have to make a switch, or some if's. Do the call/work on the overriden doInBackground(), get the result, and process it in the overriden onPostExecute() method.
I don't know if this line works, since I've had no time to experiment it, I really just thought about it, how to... :)
But I hope the thought helps at least! :)
You must implement two separate AsyncTasks with different doInBackground methods or add file downloading to existing one.
Remember that (from documentation):
The task can be executed only once (an exception will be thrown if a second execution is attempted.)