Вызов AsyncTask из другого AsyncTask
В какой-то момент моей AsyncTask, после некоторых проверок, мне нужно создать другой поток, чтобы выполнить другую работу. Таким образом, я бы хотел, чтобы на данный момент были два фоновых потока, каждый из которых делал свою собственную вещь (примерно 2-3 секунды для выполнения каждого). Идея состоит в том, чтобы максимизировать производительность на двухъядерных процессорах, таких как Atrix.
Можно ли создать другую асинтезу и выполнить ее с первой? Может ли кто-нибудь предложить лучший способ сделать это?
Спасибо!
EDIT: Мне интересно, что вообще может сделать публикацияProgress() из второй задачи... поскольку она не была запущена из Activity?
Ответы
Ответ 1
Можно ли создать другое асинтез и выполнить его с первого один?
Да, но только внутри onProgressUpdate()
или onPostExecute()
, поскольку эти методы работают в потоке пользовательского интерфейса. Поэтому запустите второй AsyncTask
в потоке пользовательского интерфейса, выбрав один из двух методов, перечисленных выше.
Мне интересно, что publishProgress() из второй задачи будет даже делать... поскольку он не был запущен с Активность
Он делает то же самое, так как вы запускаете его из потока пользовательского интерфейса.
Ответ 2
Если вы ищете механизм выполнения нескольких задач async, начиная с версии 3.0 и выше, он поддерживает метод executeOnExecutor, который позволит вы планируете параллельные задачи в пуле потоков, управляемом Async Task.
Ответ 3
AsyncTask полезен для выполнения некоторой фоновой работы при общении с основным потоком для обработки изменений пользовательского интерфейса. Похоже, это не ваше дело.
Кроме того, AsyncTask должен быть выполнен из основного потока. Из справки AsyncTask:
Существует несколько правил потоковой передачи, которые должны соблюдаться для этого класса правильно работать:
- Экземпляр задачи должен быть создан в потоке пользовательского интерфейса.
- execute (Params...) должен быть вызван в потоке пользовательского интерфейса.
Вы можете взглянуть на статью и посмотреть, что вам лучше всего подходит.
Ответ 4
Это можно сделать, используя передачу сообщений concurrency и один обработчик. Доказательство кода концепции следует:
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;
}
}
};
Я запустил первый поток при нажатии кнопки:
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();
}
});
Призывы к потоку сна должны имитировать задачу, требующую много времени.