Как сделать блокировку и синхронизированную активность? - PullRequest
1 голос
/ 30 апреля 2011

Что ж, пожалуйста, не спрашивайте меня, почему, но мне нужно начать синхронную и блокирующую активность, чтобы выполнение программы не продолжалось до его завершения.Я знаю, как сделать синхронный диалог, но как я могу выполнить синхронное действие?

Ниже приведены два подхода, которые я попробовал, но не смог:

// In the 1st activity, start the 2nd activity in the usual way
startActivity(intent);
Looper.loop();        // but pause the program here
// Program continuse running afer Looper.loop() returns
....

// Then, in the second activity's onBackPressed method:
public void onBackPressed() {
    // I was hoping the following quit() will terminate the loop() call in
    // the first activity. But it caused an exception "Main thread not allowed
    // to quit." Understandable.
    new Hanlder().getLooper().quit();
}

Я также пытался использовать другой поток, чтобыдостигните этого:

// In the first activity, start a thread
SecondThread m2ndThread = new SecondThread(this);
Thread th = new Thread(m2ndThread, "Second Thread");
th.run();
synchronized(m2ndThread) {
    m2ndThread.wait();
}

class SecondThread implements Runnable {

    Activity m1stActivity;

    SecondThread(Activity a) {
        m1stActivity = a;
    }

    public void run() {
        Looper.prepare();
        Handler h = new Handler() {
            public void handleMessage() {
                Intent intent = new Intent(m1stActivity, SecondActivity.class);
                m1stActivity.startActivity(intent); // !!!!!!!!!!!!!!
            }
        }
        h.sendEmptyMessage(10); // let it run
        Looper.quit();
    }
}

Однако этот подход не работает, потому что, когда я использую 1-е действие для запуска 2-го действия, основной поток уже находится в состоянии ожидания и ничего не делает.Таким образом, второе действие даже не было создано.(Это иронично: вы должны использовать занятие, чтобы начать занятие, но как вы можете это сделать, когда оно уже находится в состоянии ожидания?)

Ответы [ 2 ]

9 голосов
/ 30 апреля 2011

Вы не можете.

Это все, что нужно сделать.Ты просто не можешь этого сделать.Действия выполняются в основном потоке, всегда.Ваш основной поток должен активно выполнять свой цикл обработки событий.Он ВСЕГДА нарушен, чтобы заблокировать цикл событий основного потока.Всегда.

3 голосов
/ 25 марта 2015

Все действия асинхронные.Но если вы хотите заблокировать остальную часть потока приложения до завершения действия, вы можете ввести зависимость от флага, который устанавливает действие.Наиболее инкапсулированный способ сделать это - нести флаг вместе с потоком намерений / действий / возврата.Вы можете:

Объявить флаг в глобальной области видимости этого объекта:

boolean syncBlock = false;
int ASYNC_ACTIVITY_REQUEST_CODE = 1; // Arbitrary unique int

В область действия объекта, с которой начинается новое действие, входят:

Intent asyncIntent = new Intent(this, AsyncActivity.class);
syncBlock = true;
startActivityForResult(asyncIntent, ASYNC_ACTIVITY_REQUEST_CODE);
while(syncBlock) {}

И вобъект, который запустил действие:

onActivityResult(int requestCode, int resultCode, Intent data)
{
  switch(requestCode)
  {
    case ASYNC_ACTIVITY_REQUEST_CODE:
    {
      syncBlock = false;
      break;
    }

[...]
}

Это грубый хак, и если вы блокируете в своем потоке пользовательского интерфейса (например, в своем основном действии), вы блокируете все, включая другие функции пользовательского интерфейса вашегопользователи, вероятно, будут ожидать ответа, но не будут.Это большой ноно, и вы должны научиться работать с асинхронным потоком, который заставляет приложения работать на Android.Но если вы абсолютно обязаны ...

...