Использование 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:
Oh my god, существует же AsyncTask для этого. Смотрите здесь: http://it-projects.spb.ru/?p=150&lang=en
Спасибо, за статью.
Но все-таки в чем отличение между 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]
<< Главная страница