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.
Related
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
I am having a main class A, from which i create an object to class B extending Asynctask. Have set content view in A. Now in doInBackground of B, i want to update the textView of A, but its giving
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Exception. I tried declaring the setcontentview in B as well, but no use, can anyone please tell how to edit the textview of A in B??
override onProgressUpdate and call publishProgress in doInBackground
You need to call setText() from the UI thread, so either from onPreExecute(), onPostExecute() or in onProgressUpdate()
You could also use a runOnUiThread() handler in doInBackground(), but that kind of defeats the purpose of using an AsyncTask.
If the text update has to do with progress information, then you could use publishProgress()/onProgressUpdate() for that.
If it's not a progress update in a wider sense then I'm with Raghav -- you should consider another approach then.
We should not perform any ui changes in the doinBackgroud. You should and can perform in post execute. and also you can set notification in preexecute or onProgressUpdate.
Hope this will help you.
doInBackground is work thread. You have handle View in UI thread. please do it in onPreExecute(), onPostExecute() or onProgressUpdate. All these are working in UI Thread.
Of course you can pass Integer to onProgressUpdate. please notice the second paramters: AysncTask<Void, Integer, VOid>, the second parameter means the onProgressUpdate parameter type
This is my problem..i am calling a method in doInBackground of my AsyncTask class, the method is declared in my main activity class. Does it work in background thread? or i need to write the whole method inside the doInBackground ??
protected String doInBackground(String... params) {
getAllUsersfromServer();
return null;
}
this getAllUsersfromServer(); is declared in the main class. the method download some data from server using REST..
I need to run this whole process in background thread. Does it works?
Does it work in background thread?
AFAIK, Yes it works in background thread.
do I need to write the whole method inside the doInBackground ??
No need to do that.
onPostExecute works very next moment.. even my users information are
still loading
This is the main point, Its just working line by line, when it goes to execute getAllUsersfromServer(); the control goes to execute that method which gets executed in Another Background Thread. [To understand add one log print line below the method call in doInBackground and one in the method's loop and you will see even if the loop doesn't complete the doInBG log will get printed]
This happens because, your method getAllUsersfromServer(); is Void, and the Android takes it as some other independent work to be done and doesn't wait till it gets complete and keep moving to next lines.
Solution :
Just add one return type i.e. boolean getAllUsersfromServer(); and add return statement in the method return true; and in your doInBackground boolean flg = getAllUsersfromServer();
AsyncTask method doInBackground works asynchronously in a separate thread and your main thread remains available to display UI.
However what we usually do is that network processing such as "getAllUsersFromServer" is done using static HttpHelper class or method etc.
Yes it will work in the background thread. check this
I don't know why you would want to do that, but anyhow:
You'll have problems if the activity is destroyed during the async call, like if there's an orientation change. A solution to that would be to make the method static.
I have an API in one jar that uses AsyncTask to carry out some work in the background. I need to wait for the result to be returned and then do some more wok with this result.
I signal back to one class in onPostExecute() method and then the result is handled on the UI thread, but the handler needs to be defined as a callback in a different project altogether so I can't just do the work in the onPostExecute.
In the second project I need to wait for the AsyncTask to end AND for the response to be handled, then I need to display the results of the handler to a TextView in an activity in the second project.
Thread.sleep and using a CountDownLatch don't work because the handling is done in the UI thread. Is there any way to do such a thing?
If I understand correctly, you have AsyncTask in one jar and UI that needs to be updated in another jar. If you run them as one application it should not matter where they are located. Since you mentioned that some callback is involved you can just execute this callback in onPostExecute.
The following will be an approximate sequence of events
Activity from jar 2 creates async task and passes callback that knows how to update TextView as parameter to constructor
AsyncTask stores callback in instance variable
Activity executes AsyncTask
AsyncTask in onPostExecute calls method on callback with appropriate parameters
Callback updates TextView
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.