Due to android doc , The task can be executed only once.
I'm trying to run HttpClient in UI-Thread. But it allows for the only once. If I want to get another data from another link which is not yet run at the first start, how can I do it? Until I get all data when the app starts for the first time, it takes long time. Is there anyone who knows how to solve this problem ?
You're running a network operation on main thread. Use async task to run network operations in background thread (do your http requests in a background thread).
Do your networking in an async task like this:
class WebRequestTask extends AsyncTask{
protected void onPreExecute() {
//show a progress dialog to the user or something
}
protected void doInBackground() {
//Do your networking here
}
protected void onPostExecute() {
//do something with your
// response and dismiss the progress dialog
}
}
new WebRequestTask().execute();
Here are some tutorials for you if you don't know how to use async tasks:
http://mobileorchard.com/android-app-developmentthreading-part-2-async-tasks/
http://www.vogella.com/articles/AndroidPerformance/article.html
Here are the official docs from Google:
https://developer.android.com/reference/android/os/AsyncTask.html
You can call the async task multiple times whenever needed to perform the download tasks. You can pass parameters to the async task so that you can specify what data it should download (for example by passing a different url each time as a parameter to the async task). In this way, using a modular approach, you can call the same aync task multiple times with different parameters to download the data. The UI thread wont be blocked so the user experience will not be hindered and your code will be thread safe too.
You can do multiple operations in an AsyncTask
protected Void doInBackground(Void param...){
downloadURL(myFirstUrl);
downloadURL(mySecondUrl);
}
An AsyncTask can only be executed once. This means, if you create an instance of AsyncTask, you can only call execute() once. If you want to execute the AsyncTask again, create a new AsyncTask:
MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute(); //Will work
myAsyncTask.execute(); //Will not work, this is the second time
myAsyncTask = new MyAsyncTask();
myAsyncTask.execute(); //Will work, this is the first execution of a new AsyncTask.
Related
In my android application, I need to execute some operations, like creating some files in the internal storage and download some data from a server on start of the app. Only when these operations are finished, the rest of the application can work properly. So it’s my intention to show an image and a progress bar when the app is opened, and after all these operations are done, a new activity is opened.
Now, I know it’s common to put potentially long running operations like downloads and file reading/writing into async tasks. However, in my case, I can’t really continue until these operations are finished, so do I need to use Async Tasks, or is it ok for the application to block in this case?
Or should I start an Async Task and then wait for it, using the get() method?
Thanks for advices, I'd really like to do this the right way.
You care create a splash activity which should be your launcher activity.
Then in the splah, start an async task for downloading and all, then after the completion of the task, you can move to your desired activities.
You can also use a thread for this purpose; in that case, you need to handle the task completion callback using a handler or runOnUIThread mechanisms.
Better to use Async task for this.
You need to put it in an async task or different thread. Internet requests on the main ui thread will create a fatal error on the newest (android 4+) systems.
It is always better to show a loading image or progress dialog than showing a hanging white screen.
For all long blocking jobs, async is required.
If you have the splash screen as your main activity, add this code for your async task:
private class YourTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
//Do your work here
//Note that depending on the type of work, you can change the parameters
//of the async task.
return count;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
//Put here the code when your job is done, for example:
//start a new activity (your real main activity).
}
}
After that, in your oncreate method of the activity, call
new YourTask ().execute(url1, url2, url3);
I have an existing code which has an Async Task used for some request-response.
In the post execute method it sets the parsed data into some db.
Now I need to modify this code in such a way that at app launch, the data gets downloaded one by one.
i.e. I need to execute task A, then on its full completion (even the data is set) I need to start task B and so on for around 12 tasks.
Note: I need to finish the "post execute" as well before starting the next task.
I am not sure how to do this.
Please suggest.
You can do it with myAsyncTask.executeOnExecutor (SERIAL_EXECUTOR)
AsyncTask a = new AsyncTask();
AsyncTask b = new AsyncTask();
AsyncTask c = new AsyncTask();
a.executeOnExecutor (SERIAL_EXECUTOR);
b.executeOnExecutor (SERIAL_EXECUTOR);
c.executeOnExecutor (SERIAL_EXECUTOR);
Now the exection order will be a -> b -> c;
This one gets a bit messy..
Configuring a AsyncTask with SERIAL_EXECUTOR will indeed force serial execution of background logic,
that is, the logic contained within the doInBackground() calls.
SERIAL_EXECUTOR makes no guarantees as to when the onPostExecute() will be invoked.
Executing a set of AsyncTask in SERIAL_EXECUTOR mode may result in onPostExecute() of task A being
executed after the doInBackground() of task B.
If the latter demand is not crucial to your system, just use SERIAL_EXECUTOR and be happy.
But, if it is, you will need to change your architecture in a way that will force
such demand.
one way of doing so will be as follows:
class MyAsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
// do background work
return null;
}
#Override
protected void onPostExecute(Void args) {
// update UI here
new MyNextAsyncTask.execute(..); // <---------- start next task only after UI update has completed
}
}
That is: you will wait for the UI update of one operation to complete before starting the next one.
Another way, which I would probably prefer, would be to manage th entire task flow
within a single thread that internally perform att background tasks A -> B -> C ....
and, in between, issues UI update commands and waits on a ConditionVariable for these
tasks to complete
new Thread() {
ConditionVariable mCondition = new ConditionVariable(false);
void run() {
do_A();
runonUIThread(updateAfter_A_Runnable);
mPreviewDone.block(); // will be release after updateAfterA_Runnable completes!
do_B();
runonUIThread(updateAfter_B_Runnable);
mPreviewDone.block(); // will be release after updateAfter_B_Runnable completes!
etc..
}
}
Hope it helps.
The implementation depends on your requirement.
If after every call you need to update your UI you can download and save data in doInBackground() and the update in onPostExecute().
If you wanna update your UI just once then download all the data inside a loop inside your doInBackground() and also save your data in db there only and finally call your onPostExecute() just once.
If it has nothing to do with updating the UI then you can simply use Thread.
NOTE : AsyncTask order of execution will be serial only above HoneyComb below that it would be parallel.
I'm very new to programming and I have some doubts.
I have a AsyncTask which is I call as RunInBackGround.
and I start this process like:
new RunInBackGround().execute();
But I wish to wait until this call is finish its executing, before proceeding to the other statements of code.
How can I do that?
Are there any way for it?
wait until this call is finish its executing
You will need to call AsyncTask.get() method for getting result back and make wait until doInBackground execution is not complete. but this will freeze Main UI thread if you not call get method inside a Thread.
To get result back in UI Thread start AsyncTask as :
String str_result= new RunInBackGround().execute().get();
Although optimally it would be nice if your code can run parallel, it can be the case you're simply using a thread so you do not block the UI thread, even if your app's usage flow will have to wait for it.
You've got pretty much 2 options here;
You can execute the code you want waiting, in the AsyncTask itself. If it has to do with updating the UI(thread), you can use the onPostExecute method. This gets called automatically when your background work is done.
If you for some reason are forced to do it in the Activity/Fragment/Whatever, you can also just make yourself a custom listener, which you broadcast from your AsyncTask. By using this, you can have a callback method in your Activity/Fragment/Whatever which only gets called when you want it: aka when your AsyncTask is done with whatever you had to wait for.
In your AsyncTask add one ProgressDialog like:
private final ProgressDialog dialog = new ProgressDialog(YourActivity.this);
you can setMessage in onPreExecute() method like:
this.dialog.setMessage("Processing...");
this.dialog.show();
and in your onPostExecute(Void result) method dismiss your ProgressDialog.
AsyncTask have four methods..
onPreExecute -- for doing something before calling background task in Async
doInBackground -- operation/Task to do in Background
onProgressUpdate -- it is for progress Update
onPostExecute -- this method calls after asyncTask return from doInBackground.
you can call your work on onPostExecute() it calls after returning from doInBackground()
onPostExecute is what you need to Implement.
I think the easiest way is to create an interface to get the data from onpostexecute and run the Ui from interface :
Create an Interface :
public interface AsyncResponse {
void processFinish(String output);
}
Then in asynctask
#Override
protected void onPostExecute(String data) {
delegate.processFinish(data);
}
Then in yout main activity
#Override
public void processFinish(String data) {
// do things
}
I have 2 async tasks (which does server requests) running just before i leave my activity.
sometimes the activity which runs this async tasks gets stuck until the async tasks finish, and sometimes the next activity shows and gets stuck until the async tasks finishes.
my question is how do i run this task in a way in which my activity's UI doesn't gets stuck (the UI is not dependable on the responses in the async tasks)
You are probably calling AsyncTask.get() somewhere in your activities code. If you call it before the task has finished executing, it will wait untill it does finish (Thus making your UI get stuck).
Can you try this.
Create a ProgressDialog set it to indeterminate and show it.
Call AsyncTask1 and in its PostExecute call AsyncTask2. Make sure you need to call this onUiThread.
In Postexecute of Asynctask2, dismiss the Progress dialog and start the next Activity.
Make sure you start your next activity on the onPostExecute() of the first Async Task. And if you have an Async task in the new activity ,call it as the last item on your onCreate Method. Following these simple rules should help
Write the code in AsyncTask doInBackground() only and call it. So that you can check whether it is accessing any UI.
eg: TestAsync extends AsyncTask...
TestAsync async = new TestAsync();
async.execute();
Try this.
Normally, AsyncTask should run in separate thread. If you create two instance. and call execute, It should execute independently. But there may be only one thread available, So it should wait(In lower version, pool size is 1.).
#TargetApi(Build.VERSION_CODES.HONEYCOMB) // API 11
void startMyTask(AsyncTask asyncTask) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
else
asyncTask.execute(params);
}
Other way is, You should run it in normal Thread.
you are must be calling 2 activities at a time in your activity
so either you must use synchronized class or function to call asynk task
or you must use singleton class to call that asynk task so that api is called in synchronized manner
as asynk task uses main ui thread to complete the task so that can be the reason that activity is getting stuck
I am developing an application for blind people. I have to work all the time with the TextToSpeech module, GPS and Network connection.
I need to do a query like this: Consult the GPS, do a JSON call and calling the TextToSpeech(TTS) module.
I am wondering the best way to deal with the different tasks which communicate with the UI main thread. I have seen so far:
Handler objects and AsyncTask class.
I have to launch each task sequentially, so I want to call the TTS after retrieving data from the network. So I have used "mHandler.post(Runnable)" and inside that runnable calling another one and so on.
However I have seen that is recommendable the use of the AsynTask class. But in this case I think I have to implement a different class for every task, whereas I don't know if those tasks will execute sequentially. Something like:
AsyntaskClass1 at1;
AsyntaskClass2 at2;
AsyntaskClass3 at3;
at1.execute();
at2.execute();
at3.execute();
Will that tasks execute in order? Cause the TTS module have to wait for the network task to finish...
Thanks for your help,
BR.David.
You could everything with a single AsyncTask class:
private class AsyncTask1 extends AsyncTask<Object, Void, Object> {
#Override
protected String doInBackground(Object... args) {
// Get a result from the GPS.
// Make a network call
// Communicate with the TTS
}
#Override
protected void onPostExecute(Object result) {
// Return a result to the main thread
// You are only allowed to touch the UI here
}
}
No they will be executed almost simultaneously... i.e. the second asynctask will not wait for first one to finish.
I suggest you to club all the tasks in one single AsyncTask and use publishprogress() to update the UI after each task finishes.
so you can start that AsyncTask after the network finishes and the UI will get updated sequentially
eg.
public Object doInBackground(Object... params){
//do task one's stuff
publishProgress(1);
// do task two's stuff
publishProgress(2)
//do task 3
publishProgress(3)
}
public void onProgressUpdate(Integer... int){
switch(int[0]){
case 1:
//ui update for task 1
case 2:
//ui update for task 3
case 3:
//ui update for task 3
}
The execution order is not guaranteed in your example. The UI thread would launch the 3 AsyncTasks. These three tasks would then execute concurrently.
If you want to execute the code in the tasks synchronously you have at least a couple of ways to acomplish it:
Combine the three tasks into one where you have ordered the work to be done sequentially i.e:
AsyncTaskCombined task = new AsyncTaskCombined();
task.execute();
private class AsyncTaskCombined extends AsyncTask<Void, Void, Void> {
protected Bitmap doInBackground(Void... urls) {
// Initialize classes that implement the work logic
Work1 work1;
Work2 work2;
Work3 work3;
// Do the work sequentially...
work1.doWork();
work2.doWork();
work3.doWork();
}
}
Or potentially you could have 3 different AsyncTask and then in the onPostExecute of the first task create and call the second AsyncTask and in the second AsyncTask's onPostExecute create and call the third and last AsyncTask. However that seems a bit contrieved to me...
// Emil H