Android: ProgressDialog.show() crashes with getApp

2019-01-01 03:56发布

I can't seem to grasp why this is happening. This code:

mProgressDialog = ProgressDialog.show(this, "", getString(R.string.loading), true);

works just fine. However, this code:

mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);

throws the following exception:

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

Any ideas why this is happening? I'm calling this from the onCreate method.

18条回答
柔情千种
2楼-- · 2019-01-01 04:02

I don't think this is a timing issue around a null application context

Try extending Application within your app (or just use it if you already have)

public class MyApp extends Application

Make the instance available as a private singleton. This is never null

private static MyApp appInstance;

Make a static helper in MyApp (which will use the singleton)

    public static void showProgressDialog( CharSequence title, CharSequence message )
{
    prog = ProgressDialog.show(appInstance, title, message, true); // Never Do This!
}

BOOM!!

Also, check out android engineer's answer here: WindowManager$BadTokenException

One cause of this error may be trying to display an application window/dialog through a Context that is not an Activity.

Now, i agree, it does not make sense that the method takes a Context param, instead of Activity..

查看更多
皆成旧梦
3楼-- · 2019-01-01 04:02

For Android 2.2
Use this code:

//activity is an instance of a class which extends android.app.Activity
Dialog dialog = new Dialog(activity);

instead of this code:

// 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);

Remark: My custom dialog is created outside activity.onCreateDialog(int dialogId) method.

查看更多
零度萤火
4楼-- · 2019-01-01 04:05

I am using Android version 2.1 with API Level 7. I faced with this (or similar) problem and solved by using this:

Dialog dialog = new Dialog(this);

instead of this:

Dialog dialog = new Dialog(getApplicationContext());

Hope this helps :)

查看更多
浮光初槿花落
5楼-- · 2019-01-01 04:05

Had a similar problem with (compatibility) Fragments in which using a getActivity() within ProgressDialog.show() crashes it. I'd agree that it is because of timing.

A possible fix:

mContext = getApplicationContext();

if (mContext != null) {
    mProgressDialog = ProgressDialog.show(mContext, "", getString(R.string.loading), true);
}

instead of using

mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);

Place the mContext as early as possible to give it more time to grab the context. There's still no guarantee that this will work, it just reduces the likelihood of a crash. If it still doesn't work, you'd have to resort to the timer hack (which can cause other timing problems like dismissing the dialog later).

Of course, if you can use this or ActivityName.this, it's more stable because this already points to something. But in some cases, like with certain Fragment architectures, it's not an option.

查看更多
路过你的时光
6楼-- · 2019-01-01 04:06

For me worked changing

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

to

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

Weird thing is that the first one can be found in google tutorial and people get error on this..

查看更多
只靠听说
7楼-- · 2019-01-01 04:07

For Activities shown within TabActivities use getParent()

final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());

instead of

final AlertDialog.Builder builder = new AlertDialog.Builder(this);
查看更多
登录 后发表回答