AsyncTask oddity - android

I'm working on the live frames that I get from the android camera. I don't treat all the frames but when I do, I create a Thread so as to keep the ui thread responsive. The thing is, that within this new thread at some point I want to update a server so I start an Asynctask.
According to the documentation, Asynctasks should be started by the UI thread. So I use runOnUiThread to start them. In accord with the documentation, what happens is that if I change the activity or change configuration, the activity is restarted, my task dies and I never get the server's response(which is saved in a database table). I'm curious, so I tried starting the Asynctasks from the worker thread, and lo! I get the server response even if the activity has changed. What is interesting is that if my UI thread is number 1 and my worker thread is number 2, the server's response treatment happens on 1 and not 2. I can more or less understand this because thread 2 has finished so the asynctask probably falls back onto thread 1, but I really don't get why this thread is still running if I'm in an other activity? does anyone know what's happening?
I'm aware that even if this effect may seem very useful, it isn't a good idea to use it. But I'm just curious about why it works this way.

When configuration change (generally speaking), the activity is recreated. At that moment, you have 2 instances of Activity. The old one pending collection and the new one. Say that the old one had a worker thread W. W is pending collection. However, it is very possible that it is able to continue its work before it is collected. (If you create a thread with an infinite while loop, you can notice that it will stop but eventually.)
When you start the AsyncTask from the UI thread, results will be posted to the UI Thread (delivered in onPostExecute). When the activity is pending garbage collection, the onPostExecute will not be post to the ui thread that is DONE.
However, when you started the AsyncTask from the worker thread, results will be posted as long as the calling thread (your W thread) is there. "Is there" was described in the first paragraph of the answer.

Related

Looper or while in a thread?

I'm trying to understand the Looper...
This time i'm getting a little bit confused, because I've only used (until now) the while(true) condition to maintain the thread in an infinite loop.
I just want to know if it is better to use the Looper or the while(true) condition.
I've searched a possible answer to my question in internet and I was quite disappointed in finding codes that use Looper and while(true) together.
Probably I didn't get the point of using the Looper but, you know, we are here to learn... isn't it?
Looper is a mechanism that keeps thread open to process Messages that are sent to it via Handler. In that sense, they are similar to while(true) in that the Thread stays open forever (or in this case until you explicitly tell it to close). However, unlike while(true), you can send the Messages to it from another thread. Every time you create a Handler, it binds itself to the Looper thread that it was created in. Then, every time you post a message to that Handler, it processes that message on the thread in which it was created.
The most common, well-known Looper thread in Android is the main UI thread. This thread is always running. It runs code that are posted to it. Most commonly drawing operations, but if you take a view and call View#post, it will run the code in the next draw cycle. This is because all View objects have a Handler that was built on the main UI Looper thread.
The UI Looper can actually be referenced to Looper.getMainLooper() method, and you can create a Handler that posts messages to this thread like so: new Handler(Looper.getMainLooper());.
Though if you need, you could create your own Looper thread that acts as a parallel thread to the UI thread. You can't do drawing operations on it, but you could use it as a worker thread for other operations. That way you don't have the overhead of creating a new thread every time you need to do something intensive.
I just want to know if it is better to use the Looper or the while(true) condition.
I'd say, as a general rule, unless you need some very specific low-level control, use the API that are provided by the framework, whichever the framework is.
They usually take care of many aspects that would otherwise have you implement them yourself, such as messaging, task deletion, and so on...
I guess that with the while (true) loop you are trying to achieve some regular task repetition.
In this particular case, yes, use a Handler with its own Looper, so the UI Thread is not blocked, and post your Runnable instances regularly with postDelay(Runnable, long).
#DeeV 's answer already gives you a good understanding about the mentioned components, but you sure will find out everything you need in Android documentation.

Executing a Thread in Asynctask and its complications

I was wondering is it ok to execute a Thread inside the doInBackground method of Asynctask. Should I avoid using this kind of structure on my codes? And if yes, why should I avoid it? Would this cause any ineffectiveness in my apps?
In principle, there's no problem with starting a thread in the doInBackground() of an AsyncTask, but sometimes you see this done not because it's the right thing to do, but because of a misunderstanding about how AsyncTask works.
The point is that doInBackground() will automatically get executed on a background (non-GUI) thread, without you needing to create a thread for it yourself. That, in fact, is the whole point of an AsyncTask. So if you have a simple, linear task that you want executed in the background, you do it with an AsyncTask, and you don't need to do any manual thread creation.
Where you might want to start a new thread in an AsyncTask is if you want your background task to use multiple threads to complete. Suppose that you were writing an app to check the online status of various servers, and display something about their status on the screen. You'd use an AsyncTask to do the network access in the background; but if you did it in a naive way, you'd end up with the servers being pinged one by one, which would be rather slow (especially if one was down, and you needed to wait for a timeout). The better option would be to make sure that each server was dealt with on its own background thread. You'd then have a few options, each of which would be defensible:
Have a separate AsyncTask for each server.
Create a thread for each server inside the doInBackground() of your single AsyncTask, and then make sure that doInBackground() doesn't complete until all the individual threads have completed (use Thread.join()).
Use a ThreadPool / some kind of ExecutorService / a fork/join structure inside your single AsyncTask, to manage the threads for you.
I would say that with modern libraries there is rarely a need for manual thread creation. Library functions will manage all of this for you, and take some of the tedium out of it, and make it less error-prone. The third option above is functionally equivalent to the second, but just uses more of the high-level machinery that you've been given, rather than going DIY with your thread creation.
I'm not saying that threads should never be created manually, but whenever you're tempted to create one, it's well worth asking whether there's a high-level option that will do it for you more easily and more safely.
is it ok to execute a Thread inside the doInBackground method of
Asynctask.
yes it is but it really depends on your application and your usage. for example in a multithread server-client app you must create for each incoming clients one thread and also you must listen on another thread. so creating thread inside another is ok. and you can use asynctask for listening to your clients.
Should I avoid using this kind of structure on my codes? And if yes,
why should I avoid it?
If you design it carefully you do not need to avoid, for example make sure that on rotation you do not create another asynctask because for example if your user rotates 5 times you create 5 asynctasks and in each of them you create a thread that means you will get 10 threads, soon you will get memory leak.
Would this cause any ineffectiveness in my apps? Can you explain
these questions please.
I answered it above, I think better idea is using Thread Pool to minimize number of creating your threads or wraping your asynctask in a UI less fragment so you are sure you have one asynctask regardless of whats going to happen.
In any higher programming language, there is concept of multi-tasking. Basically the user needs to run some portion of code without user interaction. A thread is generally developed for that. But in Android, multi-tasking can be done by any of the three methods Thread and AsyncTask.
Thread
A thread is a concurrent unit of execution. It has its own call stack. There are two methods to implement threads in applications.
One is providing a new class that extends Thread and overriding its run() method.
The other is providing a new Thread instance with a Runnable object during its creation.
A thread can be executed by calling its "start" method. You can set the "Priority" of a thread by calling its "setPriority(int)" method.
A thread can be used if you have no affect in the UI part. For example, you are calling some web service or download some data, and after download, you are displaying it to your screen. Then you need to use a Handler with a Thread and this will make your application complicated to handle all the responses from Threads.
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each thread has each message queue. (Like a To do List), and the thread will take each message and process it until the message queue is empty. So, when the Handler communicates, it just gives a message to the caller thread and it will wait to process.
If you use Java threads then you need to handle the following requirements in your own code:
Synchronization with the main thread if you post back results to the user interface
No default for canceling the thread
No default thread pooling
No default for handling configuration changes in Android
AsyncTask
AsyncTask enables proper and easy use of the UI thread. This class allows performing background operations and publishing results on the UI thread without having to manipulate threads and/or handlers. An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread.
AsyncTask will go through the following 4 stages:
1. onPreExecute()
Invoked on the UI thread before the task is executed
2. doInbackground(Params..)
Invoked on the background thread immediately after onPreExecute() finishes executing.
3. onProgressUpdate(Progress..)
Invoked on the UI thread after a call to publishProgress(Progress...).
4. onPostExecute(Result)
Invoked on the UI thread after the background computation finishes.
And there are lot of good resources over internet which may help you:
http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html http://www.mergeconflict.net/2012/05/java-threads-vs-android-asynctask-which.html
I would say there is no problem in doing that if you need something to run concurrently beside the AsyncTask.
One issue could be one of readability (using 2 different ways for concurrency), but I really can't see the harm in that - especially if one of the tasks needs to show it's result in the UI and the other one doesn't.

How to time relinquish an Android thread?

I'm in front of a very pretty annoying problem.
I have a code to execute that can take tens of seconds. In final I need to obtain the result of that computation.
If I execute the code merely on the main thread, Android will pop up telling that the thread is blocked and asking if we want to force block.
Well the principle is normal, every OS kernel needs to know our code is still alive and not blocked.
So my question is how to inform Android we are not dead?
For instance the equivalent of a Sleep(0) or ProcessMessage() or anything... but that informs Android that we are not dead, because we are just waiting or performing something pretty long...
Please don't answer me: "let make your computation in a separate thread" since the problem would be exactly the same. The main thread would still need to sit down to know when the thread completes and its result.
You should not run any process that access a database, the internet, or takes longer then .2 seconds on the UI thread.
Asynctask is a very powerful method that allows you to thread computations, while still being able to update the UI at predetermined points. Learn to love it.
As far as letting the user know, make a please wait spinner dialog appear on the pre-execute block, and make it go away on the post execute block.
Edit: To dig into this a bit: The asynctask has three blocks that run on the UI thread onPreExecute, onPostExecute, and onProgressUpdate). In these blocks you can update the UI. Within the doInBackground block, it is its own thread, and so will not block the UI as it processes.
In practice you can set things up to notify that a process is happening in onPreExecute, notify the user of progress during a onProgressUpdate, and then present the final information/clear any please wait dialogs during the onPostExecute block. It was specifically designed to tackle the exact problem you are discussing.
Any process that locks up the system for more then 4 seconds by running on the UI thread will cause a not-responding error to be presented to the user.
http://developer.android.com/reference/android/os/AsyncTask.html
You should compute in another thread and then call back to the UI thread using http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
see http://developer.android.com/guide/components/processes-and-threads.html for more details.
I'll probably catch flack for this but, really, only use AsyncTask where appropriate! (read: quit it!)
Virgil Dobjanschi's answer here:
http://www.youtube.com/watch?v=xHXn3Kg2IQE
.. is really, really good. It is a little more complicated, but it is frequently no more complicated than the actual problem.
While there aren't a lot of details in the original question, it is likely that the best way to solve the problem is (as all answers agree) to use a separate thread. The best way to get to that other thread, though, is likely to be an intent fired at an IntentService. ... and then runOnUiThread, or a Handler, to get the response back.

Multiple async tasks not executing properly

I am trying to start 6 async tasks at a time in onCreate() of the activity. But I noticed following:
a) If I stay on same activity all the async tasks' doInBackground() execute properly.
b) If I switch to some other activity, only 4 or 5 async tasks' doInBackground() executes. Last async task's doInBackground() never executes.
Can someone tell what I might be doing wrong. I am staring different asynctasks in a for loop. If I do this in onStart(), then all the async tasks are executed again if I switch to this activity. Please help.
Here is the sample code:
For(int i=0;i<7;i++){
webServiceTask= WebServiceTask.getInstance();
webServiceTask.execute("");
}
Maybe you should consider some of the following points:
Is the WebServiceTask retrieving any information that is worth persisting (i.e. not very volatile, with a high risk of the user requesting the same data over and over again): in that case you can offload your work to an (Intent)Service and communicate the result back to your app via a ResultReceiver, or a ContentProvider (just to name a few).
AsyncTasks are not guaranteed to run to completion if no Activity or Service is around to keep your app's process alive.
If it is ok that the WebServiceTasks run after eachother, then you can probably also change your code to use only one AsyncTask that sequentially performs those tasks. You can even consider implementing AsyncTask's progress reporting mechanism.
If the operations performed by the AsyncTask(s) have no meaning once the Activity is closed, be sure to .cancel() them in your onStop() or onPause() lifecycle methods.
Keep bullet 3 of Ed Rowland's answer in mind, which I also posted in my earlier comment to your question.
Happy coding!
You need a Service of some kind to keep your process alive after the user switches away. Once your activity loses focus, Android is free to shut down your process altogether. Or your Activity. Either will cause problems, particularly if you are using the context of an Activity that has been shut down.
The Right Thing to Do (tm) is to implement a Service, and pass the operations off to the service for execution.
There are any of a bunch of reasons why only four tasks are running concurrently. Off the top of my head:
HttpConnection pools connections to servers, and throttles the
maximum number of connetions to any given server to some reasonable
value. 4 sounds about right.
your target server is throttling the number of simultaneous connections.
Your thread pool isn't as large as you think it is. Starting an API 16 (I think) the default threadpool size is one thread! (!!) Rationale: apparently Android OS developers got fed up with Android app developers doing threading wrong. Is it possible your tasks are executing serially? That would more or less fit the symptoms you describe.
But that's kind of a separate issue.

Handler vs AsyncTask

I'm confused as to when one would choose AsyncTask over a Handler. Say I have some code I want to run every n seconds which will update the UI. Why would I choose one over the other?
IMO, AsyncTask was written to provide a convenient, easy-to-use way to achieve background processing in Android apps, without worrying too much about the low-level details(threads, message loops etc). It provides callback methods that help to schedule tasks and also to easily update the UI whenever required.
However, it is important to note that when using AsyncTask, a developer is submitting to its limitations, which resulted because of the design decisions that the author of the class took. For e.g. I recently found out that there is a limit to the number of jobs that can be scheduled using AsyncTasks.
Handler is more transparent of the two and probably gives you more freedom; so if you want more control on things you would choose Handler otherwise AsynTask will work just fine.
My rule of thumb would be:
If you are doing something isolated related to UI, for example downloading data to present in a list, go ahead and use AsyncTask.
If you are doing multiple repeated tasks, for example downloading multiple images which are to be displayed in ImageViews (like downloading thumbnails) upon download, use a task queue with Handler.
Always try to avoid using AsyncTask when possible mainly for the following reasons:
AsyncTask is not guaranteed to run since there is a ThreadPool base and max size set by the system and if you create too much asynctask they will eventually be destroyed
AsyncTask can be automatically terminated, even when running, depending on the activity lifecycle and you have no control over it
AsyncTask methods running on the UI Thread, like onPostExecute, could be executed when the Activity it is referring to, is not visible anymore, or is possibly in a different layout state, like after an orientation change.
In conclusion you shouldn't use the UIThread-linked methods of AsyncTask, which is its main advantage!!! Moreover you should only do non critical work on doInBackground.
Read this thread for more insights on this problems:
Is AsyncTask really conceptually flawed or am I just missing something?
To conclude try to prefer using IntentServices, HandlerThread or ThreadPoolExecutor instead of AsyncTask when any of the above cited problems ma be a concern for you. Sure it will require more work but your application will be safer.
If you want to do a calculation every x seconds, you should probably schedule a Runnable on a Handler (with postDelayed()) and that Runnable should start in the current UI thread. If you want to start it in another thread, use HandlerThread.
AsyncTask is easier to use for us but no better than handler.
The Handler is associated with the application’s main thread. it handles and schedules messages and runnables sent from background threads to the app main thread.
AsyncTask provides a simple method to handle background threads in order to update the UI without blocking it by time consuming operations.
The answer is that both can be used to update the UI from background threads, the difference would be in your execution scenario. You may consider using handler it you want to post delayed messages or send messages to the MessageQueue in a specific order.
You may consider using AsyncTask if you want to exchange parameters (thus updating UI) between the app main thread and background thread in an easy convinient way.
AsyncTask presumes you will do something on the UI thread, after some background work is finished. Also, you can execute it only once (after this, its status is FINISHED and you'll get an exception trying to execute it once more). Also, the flexibility of using it is not much. Yes, you can use THREAD_POOL_EXECUTOR for a parallel execution, but the effort might be not worthy.
Handler doesn't presume anything, except handling Runnables and Messages. Also, it can be run as many times as you wish. You are free to decide to which thread it must be attached to, how it communicates with other handlers, maybe produce them with HandlerThread. So, it's much more flexible and suitable for some repeated work.
Check different kind of Handler examples here.
They are best interview question which is asked.
AsyncTask - They are used to offload of UI thread and do tasks in background.
Handlers - Android dosent have direct way of communication between UI and background thread. Handlers must be used to send message or runnable through the message queue.
So AsyncTasks are used where tasks are needed to be executed in background and Handlers are used for communication between a UI and Background Thread.
doInBackground - basically does work in another thread.
onPostExecute - posts the results on the UI thread and it is internally sending message to handler of main thread. Main UI thread already has a looper and handler associated with it.
So basically,if you have to do some background task,use AsyncTask. But ultimately,if something needs to be updated on UI,it will be using main thread's handler.

Categories

Resources