Android: ProgressDialog.show() сбой с getApplicationContext
Я не могу понять, почему это происходит. Этот код:
mProgressDialog = ProgressDialog.show(this, "", getString(R.string.loading), true);
работает просто отлично. Однако этот код:
mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);
выдает следующее исключение:
W/WindowManager( 569): Attempted to add window with non-application token WindowToken{438bee58 token=null}. Aborting.
D/AndroidRuntime( 2049): Shutting down VM
W/dalvikvm( 2049): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
E/AndroidRuntime( 2049): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 2049): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tastekid.TasteKid/com.tastekid.TasteKid.YouTube}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 2049): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
E/AndroidRuntime( 2049): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
E/AndroidRuntime( 2049): at android.app.ActivityThread.access$2100(ActivityThread.java:116)
E/AndroidRuntime( 2049): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
E/AndroidRuntime( 2049): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 2049): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 2049): at android.app.ActivityThread.main(ActivityThread.java:4203)
E/AndroidRuntime( 2049): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 2049): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 2049): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
E/AndroidRuntime( 2049): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
E/AndroidRuntime( 2049): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 2049): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 2049): at android.view.ViewRoot.setView(ViewRoot.java:460)
E/AndroidRuntime( 2049): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
E/AndroidRuntime( 2049): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime( 2049): at android.app.Dialog.show(Dialog.java:238)
E/AndroidRuntime( 2049): at android.app.ProgressDialog.show(ProgressDialog.java:107)
E/AndroidRuntime( 2049): at android.app.ProgressDialog.show(ProgressDialog.java:90)
E/AndroidRuntime( 2049): at com.tastekid.TasteKid.YouTube.onCreate(YouTube.java:45)
E/AndroidRuntime( 2049): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
E/AndroidRuntime( 2049): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
E/AndroidRuntime( 2049): ... 11 more
Любые идеи, почему это происходит? Я вызываю это из метода onCreate
.
Ответы
Ответ 1
Какую версию API вы используете? Если я прав насчет проблемы, то это было исправлено в Android 1.6 (API версии 4).
Похоже, ссылка на объект, что getApplicationContext()
возвращает только точки в null. Я думаю, что у вас возникла проблема, аналогичная той, что у меня была в том, что некоторые из кода в onCreate()
выполняются до того, как окно действительно будет построено. Это будет взломать, но попробуйте запустить новую тему за несколько сотен миллисекунд (мне кажется, что работа для меня работала (IIRC: 300-400), но вам нужно поработать), которая открывает ваш ProgressDialog и запускает все, что вам нужно ( например, сеть IO). Что-то вроде этого:
@Override
public void onCreate(Bundle savedInstanceState) {
// do all your other stuff here
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mProgressDialog = ProgressDialog.show(
YouTube.this.getApplicationContext(), "",
YouTube.this.getString(R.string.loading), true);
// start time consuming background process here
}
}, 1000); // starting it in 1 second
}
Ответ 2
Я использую версию Android 2.1 с API уровня 7. Я столкнулся с этой (или подобной) проблемой и решил с помощью этого:
Dialog dialog = new Dialog(this);
вместо этого:
Dialog dialog = new Dialog(getApplicationContext());
Надеюсь, что это поможет:)
Ответ 3
Для меня работала смена
builder = new AlertDialog.Builder(getApplicationContext());
к
builder = new AlertDialog.Builder(ThisActivityClassName.this);
Странно то, что первое можно найти в учебнике Google, и люди получают ошибку на этом.
Ответ 4
Я не думаю, что это проблема времени вокруг контекста нулевого приложения
Попробуйте расширить приложение в своем приложении (или просто используйте его, если у вас уже есть)
public class MyApp extends Application
Сделайте экземпляр доступным как отдельный синглтон. Это никогда не является нулевым
private static MyApp appInstance;
Сделайте статический помощник в MyApp (который будет использовать синглтон)
public static void showProgressDialog( CharSequence title, CharSequence message )
{
prog = ProgressDialog.show(appInstance, title, message, true); // Never Do This!
}
BOOM!!
Кроме того, проверьте, как работает инженер-андроид здесь: WindowManager $BadTokenException
Одной из причин этой ошибки может быть попытка отобразить приложение window/dialog через контекст, который не является активностью.
Теперь, согласитесь, не имеет смысла, что метод принимает параметр Context, а не Activity.
Ответ 5
Прочитав приведенные выше ответы, я обнаружил, что для моей ситуации исправлена проблема.
Это привело к ошибке
myButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
MyDialogue dialog = new MyDialogue(getApplicationContext());
dialog.show();
}
});
Основываясь на предыдущих ответах, в которых предполагалось, что контекст был неправильным, я изменил getApplicationContext(), чтобы извлечь контекст из Представленного представления в метод onClick.
myButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
MyDialogue dialog = new MyDialogue(v.getContext());
dialog.show();
}
});
Я не полностью понимаю работу Java, поэтому я могу ошибаться, но я предполагаю, что для моей конкретной ситуации причина могла быть связана с тем, что приведенный выше фрагмент был определен в классе абстрактной активности; унаследованный и используемый многими действиями, возможно, это способствовало тому, что getApplicationContext() не возвращает действительный контекст? (Просто догадка).
Ответ 6
Я создаю карту с подробными наложениями. Я создавал свой itemizedoverlay, как это из моей mapActivity:
OCItemizedOverlay currentLocationOverlay = new OCItemizedOverlay(pin,getApplicationContext);
Я обнаружил, что я получил бы "android.view.WindowManager $BadTokenException: Не удалось добавить исключение окна - токен null не для исключения приложения", когда был вызван мой метод itemizedoverlay onTap (когда местоположение выбрано на mapview).
Я обнаружил, что если я просто передал, 'this' вместо 'getApplicationContext()' для моего конструктора, проблема исчезла. Это, похоже, поддерживает чужой поступок. странно.
Ответ 7
Для действий, показанных в TabActivities, используйте getParent()
final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());
вместо
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
Ответ 8
Для Android 2.2
Используйте этот код:
//activity is an instance of a class which extends android.app.Activity
Dialog dialog = new Dialog(activity);
вместо этого кода:
// this code produces an ERROR:
//android.view.WindowManager$BadTokenException:
//Unable to add window -- token null is not for an application
Context mContext = activity.getApplicationContext();
Dialog dialog = new Dialog(mContext);
Примечание. Мой пользовательский диалог создается вне метода activity.onCreateDialog(int dialogId)
.
Ответ 9
Попробуйте -
AlertDialog.Builder builder = new AlertDialog.Builder(getParent());
Ответ 10
Схожая проблема с (совместимостью) Фрагменты, в которых с помощью getActivity()
внутри ProgressDialog.show()
происходит сбой. Я согласен, что это из-за времени.
Возможное исправление:
mContext = getApplicationContext();
if (mContext != null) {
mProgressDialog = ProgressDialog.show(mContext, "", getString(R.string.loading), true);
}
вместо
mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);
Поместите mContext как можно раньше, чтобы дать ему больше времени для захвата контекста. По-прежнему нет гарантии, что это сработает, это просто уменьшит вероятность аварии. Если он все еще не работает, вам придется прибегнуть к хакеру таймера (что может вызвать другие проблемы с синхронизацией, такие как отклонение диалога позже).
Конечно, если вы можете использовать this
или ActivityName.this
, он более стабилен, потому что this
уже указывает на что-то. Но в некоторых случаях, например, с некоторыми архитектурами фрагментов, это не вариант.
Ответ 11
(для будущих ссылок)
Я думаю, что это связано с различиями в контексте контекста и контекста работы, как описано здесь: http://www.doubleencore.com/2013/06/context/
Это означает, что мы не можем показывать диалог с помощью контекста приложения. Что это.
Ответ 12
Для использования диалогов внутри действий сделайте это следующим образом:
private Context mContext;
private AlertDialog.Builder mBuilder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
//using mContext here refering to activity context
mBuilder = new AlertDialog.Builder(mContext);
//...
//rest of the code
//...
}
Для использования диалогов внутри фрагментов сделайте это следующим образом:
private Context mContext;
private AlertDialog.Builder mBuilder;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View mRootView = inflater.inflate(R.layout.fragment_layout, container, false);
mContext = getActivity();
//using mContext here refering to fragment hosting activity context
mBuilder = new AlertDialog.Builder(mContext);
//...
//rest of the code
//...
return mRootView;
}
Что это ^ _ ^
Ответ 13
Что я сделал, чтобы обойти это, было создание базового класса для всех моих действий, где я храню глобальные данные. В первом действии я сохранил контекст в переменной в базовом классе следующим образом:
Базовый класс
public static Context myucontext;
Первая активность, полученная из базового класса
mycontext = this
Затем я использую mycontext вместо getApplicationContext при создании диалогов.
AlertDialog alertDialog = new AlertDialog.Builder(mycontext).create();
Ответ 14
Если вы вызываете ProgressDialog.show() во фрагменте, то для меня работало mContext для Activity.
ProgressDialog pd = new ProgressDialog((Activity) mContext);
Ответ 15
Я реализовал Alert Dialog для включения исключения в текущий вид активности. В то время как я дал это как
AlertDialog.Builder builder = new AlertDialog.Builder(context);
Учитывая то же окно Exception.I писать код для предупреждения из onCreate(). Так просто я использовал context = this;
после setContentView()
в методе onCreate()
. Получил контекстную переменную как глобальную, например Context context;
Пример кода
static Context context;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.network);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
context = this;
.......
Пример метода оповещения
private void alertException(String execMsg){
Log.i(TAG,"in alertException()..."+context);
Log.e(TAG,"Exception :"+execMsg);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
.......
Он отлично работает для меня. Фактически я искал эту ошибку в StackOverflow. Я нашел этот запрос. После прочтения всех ответов этого сообщения я пробовал так, чтобы он работал. Я думал, что это простое решение для преодоления исключения.
Спасибо,
Rajendar
Ответ 16
Если у вас есть проблема с groupActivity, не используйте это.
PARENT является статичным из родительской группы активности.
final AlertDialog.Builder builder = new AlertDialog.Builder(GroupActivityParent.PARENT);
вместо
final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());
Ответ 17
Диалог всегда создается и отображается как часть Activity. Вам нужно передать контекст Activity вместо контекста приложения.
http://developer.android.com/guide/topics/ui/dialogs.html#ShowingADialog
Ответ 18
Это распространенная проблема. Используйте this
вместо getApplicationContext()
Это должно решить вашу проблему