Вызывает диалоговое окно «Невозможно добавить окно - нулевой токен не для приложения» с getApplication () в качестве контекста - PullRequest
639 голосов
/ 27 апреля 2011

My Activity пытается создать AlertDialog, для которого в качестве параметра требуется Context. Это работает, как и ожидалось, если я использую:

AlertDialog.Builder builder = new AlertDialog.Builder(this);

Однако я опасаюсь использовать «это» в качестве контекста из-за потенциальной утечки памяти, когда активность разрушается и воссоздается даже во время чего-то простого, например, при повороте экрана. Из связанной записи в блоге разработчика Android :

Существует два простых способа избежать утечек памяти, связанных с контекстом. Самый очевидный из них - избежать выхода за пределы контекста. В приведенном выше примере показан случай статической ссылки, но внутренние классы и их неявная ссылка на внешний класс могут быть одинаково опасными. Второе решение заключается в использовании контекста приложения. Этот контекст будет существовать до тех пор, пока ваше приложение живо и не зависит от жизненного цикла действий. Если вы планируете хранить долгоживущие объекты, которым нужен контекст, запомните объект приложения. Вы можете легко получить его, вызвав Context.getApplicationContext () или Activity.getApplication ().

Но для AlertDialog() ни getApplicationContext(), ни getApplication() не могут быть использованы в качестве контекста, так как выдает исключение:

«Невозможно добавить окно - нулевой токен не для приложения»

по ссылкам: 1 , 2 , 3 и т. Д.

Итак, действительно ли это следует считать «ошибкой», поскольку нам официально рекомендуется использовать Activity.getApplication(), и, тем не менее, он не работает так, как рекламируется?

Jim

Ответы [ 23 ]

13 голосов
/ 23 ноября 2013

Если вы используете фрагмент и используете сообщение AlertDialog / Toast, тогда используйте getActivity () в параметре context.

как это

ProgressDialog pdialog;
pdialog = new ProgressDialog(getActivity());
pdialog.setCancelable(true);
pdialog.setMessage("Loading ....");
pdialog.show();
9 голосов
/ 21 апреля 2015

добавление

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

и

"android.permission.SYSTEM_ALERT_WINDOW"/> в манифесте

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

9 голосов
/ 04 ноября 2016

Я использовал ProgressDialog во фрагменте и получал эту ошибку при передаче getActivity().getApplicationContext() в качестве параметра конструктора.Изменение его на getActivity().getBaseContext() также не сработало.

Решение, которое работало для меня, состояло в том, чтобы передать getActivity();т.е.

progressDialog = new ProgressDialog(getActivity());

6 голосов
/ 02 июля 2014

Если вы находитесь за пределами действия, то вам нужно использовать в своей функции "NameOfMyActivity.this" в качестве действия активности, например:

public static void showDialog(Activity activity) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setMessage("Your Message")
        .setPositiveButton("Yes", dialogClickListener)
        .setNegativeButton("No", dialogClickListener).show();
}


//Outside your Activity
showDialog(NameOfMyActivity.this);
6 голосов
/ 01 мая 2013

Использование MyDialog md = new MyDialog(MyActivity.this.getParent());

5 голосов
/ 12 января 2013

Если вы используете фрагмент и используете сообщение AlertDialog / Toast, используйте getActivity() в параметре контекста.

Работает для меня.

Приветствия!

5 голосов
/ 22 августа 2013

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

Например, если у вас есть TabActivity в качестве хоста с двумя вкладками, и каждая вкладка является другим действием, и если вы попытаетесь создать диалог из одной из вкладок (действий) и если вы используете «this», то вы получите исключение , В этом случае диалог должен быть связан с активностью хоста, на котором размещено все и что видно. (Вы можете сказать наиболее видимый контекст родительской активности)

Я не нашел эту информацию ни в одном документе, но пытался. Это мое решение без сильного фона, если кто-то с более известными знаниями, не стесняйтесь комментировать.

4 голосов
/ 20 сентября 2016

Для будущих читателей это должно помочь:

public void show() {
    if(mContext instanceof Activity) {
        Activity activity = (Activity) mContext;
        if (!activity.isFinishing() && !activity.isDestroyed()) {
            dialog.show();
        }
    }
}
2 голосов
/ 29 ноября 2012

В моем случае работа:

this.getContext();
2 голосов
/ 01 декабря 2015

Или другой вариант - создать диалог следующим образом:

final Dialog dialog = new Dialog(new ContextThemeWrapper(
            this, R.style.MyThemeDialog));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...