Ожидание Реакции Пользователя На Dialog В Android

Прежде чем что-либо изобретать, я, конечно, Погуглил это (автор этого поста опубликовал свое решение позже).

Дело в том, что вы не можете ждать в 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

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.