понедельник, 15 марта 2010 г.

Использование Handler для запуска рабочих потоков

В приложениях часто требуется запускать так называемые рабочие потоки (worker threads), в которых выполняется какая-либо долговременная работа, например, печать документа, скачивание файла из Интернета, запись в файл (в Андроиде запись на SD карту - очень медленная операция), и так далее. Неразумно это делать в потоке, который обрабатывает UI - т.к. в этом случае приложение не будет реагировать на ввод до конца операции, и будет восприниматься со стороны пользователя как "зависшее". Для выполнения как раз таких действий из UI-потока запускаются рабочие потоки.

В этом посте будет показано, как использовать android.os.Handler для запуска таких потоков. Также показано, как динамически создается LinearLayout и динамически в него добавляется кнопка, при нажатии на которую и происходит запуск потока. Также показано использование android.app.ProgressDialog - он отображается на экране до тех пор, пока рабочий процесс не завершит свое выполнение.

Вот скриншот программки с кнопкой:



А вот скриншот с запущенным рабочим потоком:



Итак, код в студию:

package com.thecompany.testhandler;
 
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
 
public class MainActivity extends Activity {
 
private Button clickBtn;
private ProgressDialog progressDialog;
 
private Handler handler = new Handler() {
 
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressDialog.dismiss();
}
};
 
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
 
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
 
clickBtn = new Button(this);
ll.addView(clickBtn);
clickBtn.setText("Click me");
clickBtn.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View v) {
processThread();
}
});
 
setContentView(ll);
}
 
private void processThread() {
progressDialog = ProgressDialog.show(MainActivity.this, "Wait", "Running loooong process...");
 
new Thread() {
public void run() {
runLongProcess();
handler.sendEmptyMessage(0);
}
}.start();
}
 
private void runLongProcess() {
 
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
Log.e("MainActivity", e.getMessage());
}
}
}
 


Как видно, использование Handler вполне себе легко и не должно вызывать сложностей. Однако, в настоящее время для запуска рабочих процессов рекомендуется использовать AsyncTask. Подробнее об этом можно прочитать в статье Painless Threading.

В статье Android, Part III: Dynamic Layouts можно подробнее узнать о создании динамических лэйаутов. В блоге The Developer's Info можно прочитать пост Using Handler for long-time operations in Android, который и послужил отправной точкой для написания данного поста.

Ярлыки: ,

Комментарии: 2:

В 29 марта 2011 г. в 06:22 , Blogger Unknown сказал(а)...

Oh my god, существует же AsyncTask для этого. Смотрите здесь: http://it-projects.spb.ru/?p=150&lang=en

 
В 22 марта 2012 г. в 04:22 , Blogger Unknown сказал(а)...

Спасибо, за статью.
Но все-таки в чем отличение между Handler и моим собственным callback классом.
т.е
Есть долгий метод

Result doSomeThing(){}

Делаем его через хендлер
void doSomeThing(Handler handler){
new Thread(){
void run(){
handler.sendMessage() bla bla

}
}.start();

}

Либо же через свой класс CallBack

void doSomeThing(CallBack callBack){
new Thread(){
void run(){
callBack.onResult(new Result()); bla bla

}
}.start();

}

В javaDoc как-то размыто об этом сказано.
Message will then be scheduled in the Handler's message queue and processed when appropriate.

 

Отправить комментарий

Подпишитесь на каналы Комментарии к сообщению [Atom]

<< Главная страница