android multithreading and network on main thread exception; - android

Consider the scenario where I have get data from server and post it to UI in say list view , but this is an going activity ,it never stops.
taskA{ //fetches data over network
if(!update)
fetch();//network operation
}
taskB{//using this data UI is updated at runtime just like feed.
if(update)
show();//UI operation
}
taskA starts first after it completes taskB starts by that time A is sleeping and vice versa , goes , now the problems i am facing are:
both operations have to be in worker thread
both operations are going in cycle till activity is alive.
if handler is used to post UI operation to the main thread , taskB seems to stop.
Can anybody please suggest me a design to get this working?

AsyncTask is doing the job for you. You can make it as an inner class under your Activity main class.
http://developer.android.com/reference/android/os/AsyncTask.html
Example code
private class YourTask extends AsyncTask<URL, Integer, String> {
protected String doInBackground(URL... urls) {
// Fetch Data (Task A)
return "Result";
}
protected void onProgressUpdate(Integer... progress) {
// Show progress
}
protected void onPostExecute(String result) {
// Show UI after complete (Task B)
}
}

AsyncTask is what you're looking for. Check out this link for some sample code:
http://geekjamboree.wordpress.com/2011/11/22/asynctask-call-web-services-in-android/

You can also use IntentService you can check some sample code
An Android service is lightweight but more complex to setup.
AsyncTask is very easy but not recommended as it has many downsides and flaws.
You could also look into Loaders but it's not as easy as AsyncTasks.

Related

Android Async Task or not

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);

How to Sequentially execute Asynctask in a Loop?

I know there is alot of stuff AsyncTask and i've been exploring for quite some time but still havent found soultion. I have to upload images on FTP server in serialized manner. I know that on and after API 11, AsyncTask executes sequentially by default. But, NOT EXACTLY SEQUENTIAL ... So far my observations are : only DoInBackgorund() method executes sequentially , so if you have N asynctasks being called for execution , their OnPreExecute() are called independent of the execution of anyother Asynctask being executed. What i want is complete sequential execution Like this :
ASYNCTASK 1 :
OnPreExecute();
DoInBackgorund();
OnPostExecute();
Followed By :
ASYNCTASK 2 :
OnPreExecute();
DoInBackgorund();
OnPostExecute();
Followed By :
ASYNCTASK 2 :
OnPreExecute();
DoInBackgorund();
OnPostExecute();
... and so on.
Please provide me with some idea, tweak or concept to achieve complete sequential execution of async threads. Dummy code will be appreciated. Thanks in advance.
EDIT : image uploading mechanism is perfectly fine and images are being uploaded. i'am creating instances of uploadTask (my asyncTask for uploading image) and executing them in loop. Only problem is ; i've to update UI in OnPreExecute() of each thread ( to show number of image being uploaded , in TextView). This is my problem since OnPreExecute()are not being executed sequentially.
Simplest option: only have one AsyncTask, where you process all the work in a single doInBackground(), using publishProgress() and onProgressUpdate() to publish per-download results, if needed. I do not know why you think having N non-parallel AsyncTask instances is a good idea.
Or: don't use AsyncTask at all. Use your own ThreadPoolExecutor, so you have complete control over the characteristics of your jobs. Use an event bus (greenrobot's EventBus, Otto, LocalBroadcastManager, etc.) to publish the results on the UI thread.
Or: From onPostExecute() of the first AsyncTask, start the next AsyncTask in your chain.
Implement a interface callback on the OnPostExecute()
eg.
//activity
MyActivity extends Activity implements MyInterface
{
#Override
public void Task1Complete()
{
new StartTask2(getActivity, MyActivity.this).execute();
}
//Interface
public interface MyInterface
{
void Task1Complete()
}
//AsyncTask1
public class task1 extends AsyncTask<Void,Void,Void>
{
Context ctx;
MyInterface myInterface;
public task1(Context _ctx, MyInterface _myInterface)
{
this.ctx = _ctx;
this.myInterface = _myInterface;
}
doinbackground{}
onpostexecute()
{
myInterface.Task1Complete();
}

Android: do activity lifecycle events stop methods which are running?

What happens if some activity lifecycle events occur while a method is executing?
My activity has some methods where JSON text files (few tens of Kb) are written to disk, for example. Is it wrong designed?
Or, in general, consider the case where there are two instructions to be executed: the first performs an important operation, the second updates some data based on the result from the first.
Something like:
value=performOperationAndYeldResult();
updateAppData(value);
What happens if the lifecycle event occurrs after the first call and before the second, or while it's executing?
I put "long" operations in services but I cannot create a service for every critical data update all over the app. I think I am missing something so I fear for nothing. Maybe the resumed or restarted activity continues operations so they get completed.
Anyway I ask here: Are methods completed, or continued?
new PerformOperationAsyncTask(someValue);
private class PerformOperationAsyncTask extends AsyncTask<Object, Void, Object> {
protected Long doInBackground(Object... values) {
//this is taking place in secondary thread
Object returnValue = performOperationAndYeldResult(values[0]);
return returnValues;
}
protected void onPostExecute(Object result) {
//this is taking place in the UI thread
updateAppData(value);
}
}

What is the order of onPostExecute(Result) methods execution?Can i change it?

I'm implementing quite a simple task - user authorization.All network operations I've implemented via AsyncTask. And I have a problem. I have two AsyncTasks - one it is authorization which calls more low level and common for all network tasks operation (JSON parsing, REST realization etc.) which also is implemented via AsyncTask. And I have a problem: onPostExecute methods of these two operations are called in a wrong order. So the question - can I someway set the order of their execution, or may be you give me some advice how to handle all this in a right way.But don't suggest me to refuse AsyncTask and use something else. I want a right solution with AsyncTask. Thanks in advance.
It sounds like you should have a single AsyncTask for the high-level background operation. The low-level network activities should be invoked directly in the high-level doInBackground. By having two AsyncTasks running, you lose the ability to easily coordinate the timing of their individual work.
If for some reason you need to independently run the lower-level operations in an AsyncTask (that is, for purposes other than authorization), then that AsyncTask should also directly invoke the low-level network activities from its own doInBackground; however, the low-level activities should still be separate from any AsyncTask.
Run your 2. asycTask in 1. fisrt asycTask onPostExecute method. By the way you can set its order yourself.
like below,
private class task1 extends AsyncTask<URL, Integer, Long> {
protected int doInBackground(URL... urls) {
// do your stuf
return 1;
}
protected void onPostExecute(int result) {
// first task finished and second task starts
new task2().execute();
}
}
private class task2 extends AsyncTask<URL, Integer, Long> {
protected int doInBackground(URL... urls) {
// do your stuf
return 1;
}
protected void onPostExecute(int result) {
// do your stuf
}
}

Best way to launch different tasks

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

Categories

Resources