Android:ProgressDialog.show()与getApplicationContext崩溃

Fel*_*lix 108 android progressdialog

我似乎无法理解为什么会这样.这段代码:

mProgressDialog = ProgressDialog.show(this, "", getString(R.string.loading), true);
Run Code Online (Sandbox Code Playgroud)

工作得很好.但是,这段代码:

mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);
Run Code Online (Sandbox Code Playgroud)

抛出以下异常:

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
Run Code Online (Sandbox Code Playgroud)

任何想法为什么会这样?我从这个onCreate方法中调用它.

Tan*_*ner 127

我使用的是Android版本2.1,API级别为7.我遇到了这个(或类似的)问题,并使用以下方法解决:

Dialog dialog = new Dialog(this);
Run Code Online (Sandbox Code Playgroud)

而不是这个:

Dialog dialog = new Dialog(getApplicationContext());
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助 :)

  • 这是如何回答他的问题的?他问为什么第二个不起作用,而第一个不起作用. (18认同)
  • 我有一个类似的问题,但使用的是ActivityGroup.我能够解决此错误的唯一方法是使用getParent()代替. (4认同)
  • -1,'this'与我们中的一些人的'getApplicationContext()'相同. (3认同)

wtk*_*wtk 64

对我而言,改变了

builder = new AlertDialog.Builder(getApplicationContext());
Run Code Online (Sandbox Code Playgroud)

builder = new AlertDialog.Builder(ThisActivityClassName.this);
Run Code Online (Sandbox Code Playgroud)

奇怪的是,第一个可以在谷歌教程中找到,人们得到错误...


Jer*_*gan 42

您使用的是哪个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
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用1.6.我很确定任何UI操作都应该在UI线程中完成,因此在一个单独的线程中调用ProgressDialog.show()可能很容易成为一个大问题.仍然认为这很奇怪. (6认同)
  • 在我给你的例子中,你没有在另一个线程中进行UI操作,另一个线程只是回调UI线程告诉它打开对话框. (3认同)

ali*_*cat 23

我不认为这是一个关于null应用程序上下文的计时问题

尝试在您的应用中扩展应用程序(或者只在您已经拥有时使用它)

public class MyApp extends Application
Run Code Online (Sandbox Code Playgroud)

使实例可用作私有单例.这永远不会为空

private static MyApp appInstance;
Run Code Online (Sandbox Code Playgroud)

在MyApp中创建一个静态帮助器(将使用单例)

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

繁荣!!

另外,请在这里查看android工程师的答案: WindowManager $ BadTokenException

此错误的一个原因可能是尝试通过不是活动的上下文显示应用程序窗口/对话框.

现在,我同意,该方法采用Context param而不是Activity是没有意义的.


Emi*_*ile 10

阅读上述答案后,我发现根据我的情况,以下问题解决了这个问题.

这引发了错误

myButton.setOnClickListener(new OnClickListener(){
    public void onClick(View v) {
        MyDialogue dialog = new MyDialogue(getApplicationContext());
        dialog.show();              
    }
});
Run Code Online (Sandbox Code Playgroud)

基于之前的答案,建议上下文是错误的,我改变了getApplicationContext()以从传入View的按钮onClick方法中检索上下文.

myButton.setOnClickListener(new OnClickListener(){
    public void onClick(View v) {
        MyDialogue dialog = new MyDialogue(v.getContext());
        dialog.show();              
    }
});
Run Code Online (Sandbox Code Playgroud)

我不完全理解Java的工作方式,所以我可能是错的,但我猜测,对于我的具体情况,原因可能与上述代码片段在Abstract Activity类中定义的事实有关; 许多活动继承和使用,也许这有助于getApplicationContext()不返回有效的上下文?(只是一个猜测).


cip*_*erz 6

我正在创建带有逐项覆盖的地图视图.我正在使用mapActivity创建我的itemizedoverlay:

OCItemizedOverlay currentLocationOverlay = new OCItemizedOverlay(pin,getApplicationContext);
Run Code Online (Sandbox Code Playgroud)

我发现当我的itemizedoverlay的onTap方法被触发时(当在mapview上点击位置时),我会得到"android.view.WindowManager $ BadTokenException:无法添加窗口 - 令牌null不适用于应用程序"异常.

我发现如果我简单地将'this'而不是'getApplicationContext()'传递给我的构造函数,问题就会消失.这似乎支持alienjazzcat的结论.奇怪的.