Calling an AsyncTask from another AsyncTask - android

At a certain point of my AsyncTask, after some validations have been done, I need to spawn off another thread to do some other work. So I'd like two background threads at this point, each doing it's own thing (approx 2-3 seconds to execute each). The idea is to maximize performance on dual core processors like Atrix.
Is it acceptable to create another asynctask & execute it from the first one? Can anyone suggest a better way of doing this?
Thanks!
EDIT: I'm wondering what publishProgress() from the second task would even do... since it was not started from an Activity?

Is it acceptable to create another
asynctask & execute it from the first
one?
Yes, but only inside onProgressUpdate() or onPostExecute() since these methods runs on the UI thread. Therefore, start the second AsyncTask on the UI thread by choosing one of the two methods listed above.
I'm wondering what publishProgress()
from the second task would even do...
since it was not started from an
Activity?
It does exactly the same thing, since you are starting it from the UI thread.

If you are looking for a mechanism of executing multiple async tasks, from 3.0 and above it supports a method called executeOnExecutor which will allow you to schedule tasks in parallel on a pool of thread managed by Async Task.

An AsyncTask is useful for doing some background work while communicating with the main thread to handle UI changes. It appears that this is not your case.
Besides, an AsyncTask must be executed from the main thread. From the AsyncTask reference:
There are a few threading rules that
must be followed for this class to
work properly:
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
You can a take a look at this article and see what fits you best.

This can be done using message passing concurrency and a single handler. Proof of concept code follows:
private Handler myHandler= new Handler(){
#Override
public void handleMessage(Message msg){
switch(msg.what){
case 0:
Toast.makeText(Main.this,"Message0", Toast.LENGTH_SHORT).show();
Thread thread= new Thread( new Runnable() {
public void run() {
try {
Thread.sleep(3000);
}
catch(Exception e){}
myHandler.sendEmptyMessage(2);
}
});
thread.setDaemon(true); // <== I am a service provider. KILL ME if the non-daemon thread ConfuseText quits
thread.start();
break;
case 1:
Toast.makeText(Main.this,"Message1", Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(Main.this,"Message2", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
break;
}
}
};
I launched the first thread on a button click as in:
ON CLICK HANDLER
threadButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Thread thread= new Thread( new Runnable() {
public void run() {
try {
Thread.sleep(1000);
}
catch(Exception e){
}
myHandler.sendEmptyMessage(0);
try {
Thread.sleep(3000);
}
catch(Exception e){
}
myHandler.sendEmptyMessage(1);
}
});
thread.setDaemon(true); // <== I am a service provider. KILL ME if the non-daemon thread ConfuseText quits
thread.start();
}
});
The calls to thread sleep is to mimic a time intensive task.

Related

How to run a code when all threads are done

I am new to threading and i went through many post in stack overflow and find many solution for my problem but i am not sure which one is best for which condition.
First thing first, my problem is that i want to update one JSON file
when all threads are done with the bitmap generation at a specific path so
that i can get that all those image and update JSON file. So in
simple word my i want to run some code when all thread are done with it
execution and major requirement is that i don't want my main to be blocked because of this.
What i have found out
thread. join
excutorServive
android-priority-jobQueue (link)
Mutex in threadpool ( also let me know if any other is there)
I am confused which one is the best way to tackle my problem. if any
android expert out there can summarise that for following the two
scenerio what is the best available in android.
wait till when all thread completes
don't wait and get informed when all completes
You can have counter for your threads, after each thread is complete check how many have already completed, if not all completed, increment the number of completed threads and the last thread to complete will then run the piece of code.
You can do it like this.
In your thread:
private Runnable runnableThread= new Runnable() {
#Override
public void run() {
try {
if (lastThreadDone){
handler.sendEmptyMessage("SUCCESS");
}
}
catch (Exception ex) {
throws ex;
}
}
};
lastThreadDone is boolean which will become true if the process is done, this is base on how you implement it.
then in you handler:
#SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
try {
switch (msg.what) {
case "SUCCESS": {
// your code here
break;
}
case "FAIL":
break;
default:
break;
}
}
catch (Exception ex) {
throw ex;
}
super.handleMessage(msg);
}
};
I would use a completion service and then poll until all tasks are finished. When they are done, the json file gets updated. The problem is that you need to do this async or you risk to block the ui. Therefore I would encapsulate the work with the completion service inside an intent service. If you need to update the ui you then can post local broadcasts from the intent service.
Furthermore for you cases
wait till when all thread completes
only do this when you are already on a background thread like intent service or async task
don't wait and get informed when all completes
implies the case above. Do the work async and notify the ui or some listening component with broadcasts, content observers, handlers or the 'onPostExecute' if you are using async task.

Usage of a handler

I'm recently getting involved in some concurrent programming specially with Java and Android.
I have some questions regarding Handlers.
1 - It is known that we need to associate a Handler with a thread, and it will run on the thread it was invoked on. However, in some examples on SO, the user is doing
public class MainActivity extends Activity
{
private Handler handler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState)
{
handler.postDelayed(runnable, 1000);
}
private Runnable runnable = new Runnable()
{
public void run()
{
//Do whatever
handler.postDelayed(this, 30000);
}
};
In this example, I assume we are doing the Handler thing on the UI Thread, RIGHT ?
Can I do a network operation here in place of //DO Whatever ? I don't think so, because we are on the main thread.
Is doing this pointless ? As one may use AsyncTask to replace this task ?
How can I apply this same example but not on the UI thread, rather a seperate thread ?
Do thread or Runnables have something similar to post delayed ?
Is it common to use the handler just for its postdelayed feature and not the main task handlers are made for, ie, being the middle man between the thread and the UI/Activity ?
Handlers are useful only when you want update UI. As you may know we cannot update UI from non UI Thread. If you are going to do some network stuff in background thread, and then update UI, you have to use Handler class or AsyncTask or you can do like this:
(from non UI Thread)
SomeView.post(new Runnable() {
//updating UI
});
If whatever you are doing is "heavy" you should be doing it in a Thread. If you do not explicitly start it in its own thread, then it will run on the main (UI) thread which may be noticeable as jittery or slow to respond interface by your users.
Interestingly when you are using a thread it is often useful to also use a Handler as a means of communication between the work thread that you are starting and the main thread.
A typical Thread/Handler interaction might look something like this:
Handler h = new Handler(){
#Override
public void handleMessage(Message msg){
if(msg.what == 0){
updateUI();
}else{
showErrorDialog();
}
}};
Thread t = new Thread() {
#Override
public void run(){
doSomeWork();
if(succeed){
//we can't update the UI from here so we'll signal our handler and it will do it for us.
h.sendEmptyMessage(0);
}else{
h.sendEmptyMessage(1);
}
} };
In general though, the take home is that you should use a Thread any time you are doing some work that could be long running or very intensive (i.e. anything network, file IO, heavy arithmatic, etc).

How to implement the communication between Thread and AsyncTask

I am developing an application using Android SDK. In this application I am facing a problem when an Activity starts a Thread. The new Thread starts an AsyncTask, but the Thread has to wait for completion of the AsyncTask execution.
Is it possible to start AsyncTask in a thread, and if so, how should it be implement?
Please can anyone share your experience with me about this kind of tasks.
Thanks in advance
You should not create an AsyncTask from a thread other than main thread.
If you should wait anyway, why create AsyncTask? perform it on the thread.
just say thread to sleep for some times and then check a variable again like this
in below code someValue was setted in asynctask postExecute method
new Thread(new Runnable(){
#Override
public void run(){
while(!someValue) {
try {
Thread.sleep(200);
} catch {
Log.i("LOG", "ERROR");
}
}
Log.i("LOG", "Async Task Finished");
}
}).start();

Android wait() not working

This is my first question here, so please forgive me if I disobeyed any of the forum rules.
I need my program to wait for 3 seconds and then change the Content View
My code is:
setContentView(R.layout.logout);
new Thread(new Runnable() {
#Override
public void run(){
try {
synchronized(this){
wait(3000);
}
}
catch(InterruptedException ex){
}
}
}).start();
setContentView(R.layout.main);
The program works with no errors, but there is no waiting. When it gets to this part, it just shows the "main" layout without showing the "logout" layout at all.
What is wrong in my approach?
As people noted, don't sleep on or otherwise block the UI thread, but you seem to be aware of this with the new thread you create.
Now for why it doesn't behave as you want:
Right now, you call setContentView(), start a new thread, call setContentView() a second time on the UI thread -- this happens in quick succession with no delay/wait/sleep inbetween. The wait(3000) happens in the new thread you started -- so that new thread starts, waits for 3000ms, then exits. It's an expensive no-op.
You would need to make the second call to setContentView() from inside that new thread's run() method to get the desired effect. Also, you should use sleep() instead of wait() -- wait() is a low-level tool for synchronizing threads while sleep() is the usual "don't continue for X amount of time".
Let me propose a better way:
An arguably nicer and much lighter approch is using Handler.postDelayed() -- this allows you to invoke a Runnable on the UI thread after a delay:
setContentView(R.layout.logout);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setContentView(R.layout.main);
}
}, 3000);
Edit to reply to your comment:
Define and find the button before the Runnable as a final variable, this way you can access it later from inside the Runnable.
Please note that to reference the this instance of the surrounding class from inside an anonymous inner class (your new Runnable()), you need to prefix it with the class name of the surrounding class (your Activity class):
final View submitButton = findViewById(R.id.submit_button);
setContentView(R.layout.logout);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setContentView(R.layout.main);
// adapt to your actual Activity class name:
submitButton.setOnClickListener(YourClassName.this);
}
}, 3000);
wait() doesn't wait for a certain amount of time, but rather has the current Thread wait for this to do a notify() for a maximum amount of time. What you are looking for, is Thread.sleep().
And at the moment the only thing that will be waiting, is the additional thread you are spawning, not the activity itself. That's why I'd suggest you look at Handler.postDelayed(), CountDownTimer or AsyncTask. Handling threads is very low-level.
Your code not work to sleep UI thread.To sleep UI thread try this code
new Handler().postDelayed(new Runnable()
{
public void run()
{
setContentView(R.layout.main);
}
}, 3000);
Try using Sleep() instead of Wait()
android.os.SystemClock.sleep(3000)
As far as i can understand the wait is happening in the new thread where as you are calling setContentView(R.layout.main) in the current thread.
Try
setContentView(..)
synchronized(this) {
this.wait(1000);
}
setContentView(..)
Please note sleeping or waiting in the UI thread is not a best practice though.

android thread: how worker thread send signal to main(GUI) thread?

I have a gui thread starting a new thread to do some busy things. The GUI thread will wait the worker thread to be completed, in the mean time the GUI need to be responsive.
Psedo code:
main thread:
start_thread();
wait_thread_done();
work thread:
doing_sth();
notify_main_thread();
What is the easiest way to do this in android?
The easiest way to do this is with Android's AsyncTask. The documentation is here
http://developer.android.com/reference/android/os/AsyncTask.html
And you can call Activity.runOnUiThread() to update the UI from your background task.
A small working snippet :
new Thread() {
public void run() {
handler.post(new Runnable() {
public void run() {
try{
// **Do the GUI work here**
} catch (Exception e) { }
}});
};
}.start();
Call Activity#runOnUiThread(Runnable), the Runnable you pass to that method will execute on the GUI thread.
Or use an AsyncTask - which is the proper way to do it.
waiting for result will make gui thread unresponsive. you need to use AsyncTask and override onPostExecute to perform operation required when background thread is done

Categories

Resources