Показать диалоговое окно везде, если я не знаю текущий контекст?

Я должен показать диалоговое окно на переднем плане в результате фоновой операции http.

Когда диалоговое окно должно появиться, оно может быть везде, контекст может быть изменен, например, я начал новую активность.

Если я использую applicationContext для отображения диалогового окна, я получаю:

05-04 17:32:32.560: E/AndroidRuntime(3663): android.view.WindowManager$BadTokenException: невозможно добавить окно -- токен null не для приложения

Итак... Как я могу достичь своей цели?

какие-либо предложения?


person Noodles    schedule 04.05.2012    source источник
comment
Вот аналогичный вопрос: Всплывающее диалоговое окно Android из фонового потока   -  person Sam    schedule 04.05.2012
comment
Вы видели мой ответ?   -  person dreamtale    schedule 08.05.2012


Ответы (4)


Вам нужен способ уведомить свою активность переднего плана о завершении операции, вы можете сделать это, зарегистрировав слушателя, поскольку вы не разместили никакого кода, я сделаю предположения.

Есть два способа, которыми вы можете уведомить об активности переднего плана, о которой я знаю, первый способ - использовать широковещательные намерения, здесь есть вопрос, касающийся их Android BroadcastReceiver в Activity. Вы можете запустить широковещательную рассылку из своей фоновой операции и зарегистрировать свою активность в качестве получателя.

См. здесь http://developer.android.com/reference/android/content/Context.html#sendOrderedBroadcast%28android.content.Intent,%20java.lang.String,%20android.content.BroadcastReceiver,%20android.os.Handler,%20int,%20java.lang.String,%20android.os.Bundle%29 и здесь http://developer.android.com/reference/android/content/BroadcastReceiver.html

Второй способ — зарегистрировать прослушиватель с вашим классом, который выполняет фоновую операцию, например (псевдокод)

@Override
protected void onResume() {
    BackgroundOperator.registerListener(this);
}

@Override
protected void onPause() {
    BackgroundOperator.unregisterListener(this);
}

public void onOperationComplete(...) {
    // TODO: Show your dialog here
}

Где ваш слушатель может быть примерно таким (который может реализовать ваша активность):

interface BackgroundOperatorListener {
    void onOperationComplete(...);
}

Идея здесь заключается в том, что ваша активность переднего плана будет текущим зарегистрированным слушателем, поэтому она будет получателем обратного вызова onOperationComplete(...), и затем вы можете показать свой диалог,... может быть любое количество аргументов для передачи к вашей деятельности, когда операция завершена.

person Ian Warwick    schedule 04.05.2012
comment
проблема в том... как узнать, какая активность переднего плана? - person Noodles; 04.05.2012
comment
хорошо, я обновил свой ответ, чтобы действия регистрировались в onResume и onPause, это гарантирует, что только действие переднего плана получит обратный вызов из фоновой операции, надеюсь, это поможет. - person Ian Warwick; 05.05.2012
comment
Кстати, если вы делаете веб-запросы, я настоятельно рекомендую посмотреть презентацию Google IO REST Вирджила Добьянски youtube. .com/watch?v=xHXn3Kg2IQE он описывает аналогичный метод (в отношении своего класса Service Helper) - person Ian Warwick; 08.05.2012

Когда бы и где бы вы ни создавали диалог, вы были бы в действии, верно? Почему бы просто не использовать это действие в качестве контекста?

В моем собственном коде я создаю вспомогательный класс, который создает для меня диалог. В этот вспомогательный класс я передаю текущее действие, заголовок и сообщение. Он создает диалог и возвращает объект AlertDialog, которым я могу управлять.

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

person Gophermofur    schedule 04.05.2012
comment
Нет, я не могу, потому что, пока я жду фонового результата (используя обработчик), я могу начать новую активность, изменяющую текущий контекст. Обработчик предыдущего действия может отображать диалог не в том действии, где находится обработчик (ваше решение), а в новом. - person Noodles; 04.05.2012

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

поэтому см. этот поток: Как получить любой идентификатор самой верхней активности ?

Редактировать: Отображение диалогового окна в фоновом режиме не очень удобно для пользователя, вы можете отправить уведомление или просто сделать длинный тост.

person dreamtale    schedule 04.05.2012

На мой взгляд, лучший способ - создать одно новое действие и использовать его как диалог. Шаги:

  1. Создайте новую активность, например (чтобы она была оригинальной) MainActivy.

  2. Заполните связанный файл activity_main.xml по мере необходимости.

  3. В вашем AndroidManifest.xml перепишите эти строки.

    <activity
            android:theme="@style/AppTheme.Dialog"
            android:name="com.myapp.original.example"
            android:label="@string/timy_titlle" >
    
  4. Вызовите свою MainActivity, теперь преобразованную в Dialog, из других действий, используя класс Intent.

Если вы используете Action Bar Compact, вы можете следить за этим другие шаги.

person Community    schedule 02.04.2014