Based on Android developer's document web-page AsyncTask, Thread, it is possible to send cancel() request to AsyncTask's thread. Albeit I have sent the cancellation request and it was successful, the thread stills running. Any idea to stop the execution?
button.setOnClickListener {
Log.i(TAG, asyncTaskObj.status) // RUNNING
if (asyncTaskObj.status == AsyncTask.Status.RUNNING) {
asyncTaskObj.cancel(true)
Log.i(TAG, asyncTaskObj.isCancelled) // True
}
Log.i(TAG, asyncTaskObj.status) // RUNNING
}
Plus, is there any simple alternative to AsyncTask, which let's restart execution of the thread? (Obviously restarting AsyncTask is not possible Q&A-2)
One more thing, I have read following questions Q&A-1, Q&A-2. However, the answers do not work for me. For instance, there is no isRunning variable.
P.S. My code is in Kotlin. Please share your idea in either Java or Kotlin.
It is impossible to immediately cancel a thread from the outside like that safely. You don't know what operations it might be running, what locks the thread might hold, etc. Because of that, cancel doesn't actually stop the thread immediately. It sets a flag, and it's the job of the AsyncTask to check the flag and end itself by returning from doInBackground. Do not assume any canceled thread or task will stop running instantly. If your code requires that, you need to fix your code.
As for restarting- from scratch? Create a new instance of the AsyncTask with the same parameters. From where you left off? You can do it in a couple of ways, but it takes a lot of work. And AsyncTask is not suitable for that because its thread is a shared resource among all tasks, you'll need to use an actual Thread for that.
Related
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.
I'm building an Android library to collect data from the host app and send this data to an online server in the background. I realize that this would require some sort of multi-threading/use of a service/forking.
The application simply keeps adding data through library calls, and the library should handle the sending of this data in the background without disturbing the main UI.
How should I got about making this library? Should the entire library run on an Android Service? Should I just use another thread? This is my first foray into parallelism. I'm not sure what the best way to do this is.
A detailed response is appreciated.
Some of the answers aren't quite correct. Services (Android Service component) are NOT made to run in the background, they run in the default UI thread.
In all honesty, the question shouldn't be service or thread or anything. Your library does NOT need to kick start a service, it could simply be a class (singleton/static, whatever it is) that should extend AsyncTask (or anything else running in the background that I'll explain in a bit) and use the doInBackground method to send stuff to the server. Note AsyncTask is nothing but a Thread internally. So here's what I would do:
Let's call your library's main class that interfaces with your server ServerHelper. You can make this a singleton (or static but that's a separate discussion). Within this class create an innerclass say ServerHelperCommandTask and extend AsyncTask. You really should review AsyncTask in detail to understand how that works. Because you would be asked to override doInBackGround. Anything you put in this method will autmoatically get exectued in a separate thread off the UI. Then a callback is invoked called onPostExecute that you can override as you will get the result from doInBackground here. This OnPostExecute is called in the mainThread so you can check for say error results here, etc etc.
This would be the simplest method; however, there are many other methods and libraries that help you with networking and deal with all the background stuff internally. Google just release a library called Volley which you may be able to plugin and use as it would do all the parallel processing for you. But that may take a bit of learning curve. Hope you understand AsyncTasks as in your case if the data pushed isn't a lot, then AsyncTasks is the way to go. Also note that you can call multiple AsyncTasks but while that seems on the surface that it is kicking off multiple parallel threads, that isn't quite accurate since honeycomb as internally you can call 5 Asynctasks but all 5 of those tasks will be executed sequentially so you wouldn't have to worry much about serializing.
Service would be a more reliable solution for situation You described.
I mean running background threads from service, not from Activity. Service itself does not provide separate thread by default, by the way.
The point is that Services have higher priority than acitivities so they will be destroyed with less probabilty, so your long-running task won't be interrupted.
You could do both but here's pros and cons for each solution :
Services are made to run in the background, even when your app is not in the foreground. sers usually don't like having services running for nothing.
From your description it seems that you would only need to have this thread running when the app is in foreground right ?
If so, a normal thread could do the job.
However, a service might be easier to implement.
Hope it helps
You should definitely use a Service in this situation. Async tasks and manually creating a thread is not really suitable for computations that need to run in the background for network communication. Use the Async task for long running local computations (e.g. for an algorithm doing sorting).
Note that if you use a service, it will by nature NOT run as a background thread! You need to handle threading manually. In order to save yourself from this hassle (especially if it is your first time with multi-threading) use an IntentService!
The IntentService may be invoked using the startService method as with any other service, but the IntentService class is able to handle multiple invocations as in a producer/consumer pattern. This means that you can queue commands automatically to the service just using the startService method. In the IntentService class that you make, you can then handle different types of commands by looking at the given action inside of the intent that is sent along as a parameter in the startService method.
Here is an example of how the implementation of an IntentService:
public class SimpleIntentService extends IntentService {
public SimpleIntentService() {
super("SimpleIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
String commnad = intent.getAction();
//handle your command here and execute your desired code depending on this command
}
}
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.
I wrote an AsyncTask and most of the time there is no delay between its constructor been called and its doInBackground been called (0 ms delay).
But whenever contacts syncing is happening at the background, I often experience 1-3 seconds delay between my AsyncTasks's constructor and doInBackground. This delay is unacceptable in my circumstances.
I understand that AsyncTask is a background thread and this problem can be solved by using Thread and setting its priority higher. But what I want to found out is, how do I know what's causing my AsyncTask's doInBackground from being called?
I used adb shell top -m 10 and the process usage seems quite normal when this issue happened.
Any help is appreciated.
thanks
I also face this issue for long period, but now it is solved. Use the code below
new AsyncTaskName().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
instead the code
new AsyncTaskName().execute();
it would solve the problem of running doInbackground late.
We generally don't bother about task scheduling by the jvm. And infact we need not to bother also.
If something needs to be done as quick as possible in your application do it in the constructor itself or use onPre of Asynctask (Remember it execute on UI thread).
But i agree there is something fishy in the doInBackgroud calling in Android AsyncTask
i itself had witnessed the doInbackground didn't get called after onPre. You can google this also. many people had faced it.
I moved to use Traditional Thread.
I wrote my own Asynctask using Traditional thread at core and to mimic onPre and onPost i used Handler. You can go for that option also.
It's important to distinguish between creating and executing the task. (An ASyncTask has a separate execute() method, as well as a constructor, as you have noticed.)
Creating a thread is potentially quite expensive, so you might find that creating the task in advance, and then only executing it at the correct time, gives better results.
If the background operation is likely to be repeated often, you may also find that an IntentService, which handles requests one-at-a-time in a background thread, is more suitable.
I have 2 questions in terms of android development and threads
1) When do you think I should use threads in android development?
2) If I have the main UI thread waiting on some variable to be set before it displays a toast, then I thought about having a while(true) loop in a sperate thread that keeps checking that variable. Now if the variable is set, how do I call the method on the first thread (The UI thread) that will display a toast
Thank you so much
Using threads directly is not necessary in most cases. The android facilities for threaded programming are great, and easy to use.
You have about three options to call the UI thread from another thread:
Handler - set an handler on the other thread from the UI thread, and send it a message when need.
AsyncTask - Perform the main task in background, but modify the UI before, during and after completion.
PerformOnUiThread - call this method with a runnable to modify the UI on the UI thread.
Good article to read about is Painless Threading.
Never have a while(true) loop that continuously runs. It'll burn massive amounts of resources and, in your case, accomplish very little.
Threads are good to run for (mainly) background tasks and resource intensive tasks (so that you don't block the UI thread). To create a new Thread, use the following:
new Thread(new Runnable(){
public void run(){
//do stuff here.
}
}
).start();
You can also look into the Android AsyncTask to avoid using Threads directly.
Depending on the type of app you are working on/with, proper use of Theads can be key to having a fast and responsive UI.
Key Rule:
If you need to to anything that accesses the filesystem, network, image loading, or anything that requires more than simple value or state checks, immediately launch and perform that effort in a thread. As already stated here, a number of options are available, although myself I usually use:
change_UI_if_needed_to_indicate_click_response();
new Thread(new Runnable(){
do stuff here ;
}).start()
You can also use standard (non-inline) thread objects like this.
That may be bad practice, I don't know. Anyway, it works well for me, and isn't really the point of your question.
If you want to run something on the UI thread using standard Java, instead of specialized Android object that specifically allows for such things, there is a post(Runnable) method attached to each and every view. For me, that's the easiest my to get code back onto the UI thread.
myView.post(new Runnable{
codeForUI();
});
My general rule is to try to never run anything on the UI thread that does not need to be there. Hope that helps.
You must use thread, if you want to prevent application from the current error or crash "Application not responding".
i use it when i call web services, geolocations.
Good frensh article:
http://souissihaythem.blogspot.com/2011/08/application-not-responding.html
http://souissihaythem.blogspot.com/2011/08/application-not-responding-solution.html