Прежде чем что-либо изобретать, я, конечно, Погуглил это (автор этого поста опубликовал свое решение позже).
Дело в том, что вы не можете ждать в UI-потоке, а Activity предоставляет событийную модель работы с диалогами: при закрытии диалога вызывается общий обработчик с идентификатором диалога.
Мне такой подход показался не очень удобным и я решил сделать всё по-своему.
Поскольку мы не можем заставить поток пользовательского интерфейса ждать, давайте создадим еще один поток и заставим его ждать, и если это так, то мне понадобится механизм синхронизации потоков.
Для этой цели я написал базовый мьютекс.
Метод lock() не возвращает управление до тех пор, пока не будет вызван метод unlock().
Далее я создал класс для работы с диалогом и включил в него мьютекс.public class Mutex { public synchronized void lock() throws InterruptedException { this.wait(); } public synchronized void unlock() { this.notify(); } }
Класс инициализирует диалог и сохраняет ответ пользователя после завершения работы с диалогом.
Я опустил реализацию некоторых методов класса, чтобы сосредоточиться только на важной части реализации.
Всем кнопкам назначены обработчики(1), которые сохраняют возвращаемое значение в переменной и затем закрывают диалог.
Обработчик закрытия диалога (2) освобождает мьютекс.
Функция интерфейса (3) ожидает освобождения мьютекса.
public class SyncDialog {
private Dialog mDialog;
private Mutex mMutex;
private int mResult;
private Button mYesButton;
private Button mNoButton;
private Button mCancelButton;
public SyncDialog(Context context) {
mMutex = new Mutex();
mDialog = new Dialog(context);
mDialog.setContentView(R.layout.dialog);
findViews();
mYesButton.setOnClickListener(new OnClickListener() { // (1)
public void onClick(View v) {
mResult = YES_RESULT;
mDialog.dismiss();
}
});
mNoButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mResult = NO_RESULT;
mDialog.dismiss();
}
});
mCancelButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mResult = CANCEL_RESULT;
mDialog.cancel();
}
});
mDialog.setOnDismissListener(new OnDismissListener() { // (2)
public void onDismiss(DialogInterface dialog) {
mMutex.unlock();
}
});
}
public void waitForResponse() throws InterruptedException { // (3)
mMutex.lock();
}
}
Ну, собственно, то, что я изначально хотел: метод, ожидающий реакции пользователя (2).
Он должен работать в отдельном потоке.
Сначала мы создаем SyncDialog в UI-потоке (1), затем в фоновом потоке отправляем инициализацию и запуск диалога (3) в UI-поток, ждем (4) и обрабатываем результат (5).
public class MyActivity extends Activity {
private SyncDialog syncDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
syncDialog = new SyncDialog(this); // (1)
}
public void processDialogs(String. questions) { // (2)
for (final String question : questions) {
runOnUiThread(new Runnable() { // (3)
public void run() {
syncDialog.setText(question);
syncDialog.show();
}
});
int response;
try {
syncDialog.waitForResponse(); // (4)
response = syncDialog.getResult();
} catch (InterruptedException e) {
response = SyncDialog.CANCEL_RESULT;
}
if (response == SyncDialog.YES_RESULT) { // (5)
Log.i(question, "Yes");
}else if (response == SyncDialog.NO_RESULT) {
Log.i(question, "No");
}else
break;
}
}
}
Вы можете запустить процессDialogs(), используя AsyncTask. public class DialogsTask extends AsyncTask<String, Void, Void> {
@Override
protected Void doInBackground(String. params) {
processDialogs(params);
return null;
}
}
Для последовательного отображения диалоговых окон с использованием событийно-ориентированного подхода единственная идея, которая пришла мне в голову, заключалась в том, чтобы создать список структур, хранящих данные для отображения диалога, и по закрытии диалога инициализировать новый диалог следующей структурой.
в списке.
Мне этот способ показался совершенно неудобным.
Надеюсь, статья будет полезна тем, кто искал решение подобной проблемы.
Спасибо за внимание.
Полный исходный текст примера можно посмотреть здесь .
Теги: #Android #threads #asynctask #dialog #разработка Android
-
Рбк Нужны Деньги
19 Oct, 24 -
Контроль Версий В Appscript
19 Oct, 24 -
Открытая Разработка Игры - Отчет №0
19 Oct, 24