Android: ProgressDialog.show()在getApplicationContext的情况下会崩溃。

8 浏览
0 Comments

Android: ProgressDialog.show()在getApplicationContext的情况下会崩溃。

我似乎无法理解为什么会发生这种情况。这段代码:\n

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

\n运行得很好。然而,这段代码:\n

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

\n会抛出以下异常:\n

W/WindowManager(  569): 尝试添加一个带有非应用程序令牌WindowToken{438bee58 token=null}的窗口。正在中止。
D/AndroidRuntime( 2049): 关闭虚拟机
W/dalvikvm( 2049): 线程id=3: 由于未捕获的异常(组=0x4001aa28),线程退出
E/AndroidRuntime( 2049): 未捕获的处理程序: 线程主要是由于未捕获的异常退出
E/AndroidRuntime( 2049): java.lang.RuntimeException: 无法启动组件信息{com.tastekid.TasteKid/com.tastekid.TasteKid.YouTube}的活动:android.view.WindowManager$BadTokenException: 无法添加窗口 - 令牌null不是应用程序的令牌
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: 无法添加窗口 - 令牌null不是应用程序的令牌
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

\n有任何想法为什么会发生这种情况吗?我是从onCreate方法中调用的。

0
0 Comments

问题的原因是在使用ProgressDialog的show()方法时,getApplicationContext()返回的对象引用指向null。可能是因为在onCreate()方法中的一些代码在窗口构建完成之前就被执行了。

解决方法是通过在几百毫秒后启动一个新的线程来打开ProgressDialog并执行其他需要的操作(例如网络IO)。示例代码如下:

public void onCreate(Bundle savedInstanceState) {
    // do all your other stuff here
    new Handler().postDelayed(new Runnable() {
        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
}

该方法通过在UI线程中调用Handler来实现在延迟一段时间后打开ProgressDialog。这样可以确保在窗口构建完成后再执行相关操作。

该问题在Android 1.6(API版本4)中已经修复。如果使用的是较早的版本,建议升级到1.6或更高版本以解决该问题。

在上述讨论中,某些情况下在另一个线程中进行UI操作可能会导致问题,但实际上上述示例中并未在另一个线程中进行UI操作。另一个线程只是通过回调UI线程告知其打开对话框。

还有人指出在定时器中使用的延迟时间过长可能导致问题。建议设置较短的延迟时间,并在每次尝试之前检查应用程序是否准备好,并在准备好后重新延迟执行操作。同时还建议限制尝试的次数,以避免无限循环。

总之,根据具体情况选择合适的方法来解决该问题。

0
0 Comments

问题出现的原因是在使用ProgressDialog.show()方法时,使用了getApplicationContext()作为参数,这会导致应用程序崩溃。解决方法是将getApplicationContext()替换为当前活动类的实例ThisActivityClassName.this。

原因是getApplicationContext()方法返回的是应用程序的上下文,而不是当前活动的上下文。应用程序的上下文不能用于显示UI元素,只能在特定情况下使用。因此,在显示进度对话框时,必须使用当前活动的上下文。

以下是解决方法的代码示例:

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

这是一种正确的做法。除非必要,否则不要使用ApplicationContext,并且绝对不要使用它来显示UI元素。这就是活动(以及最终的片段)的作用。

如果在例如点击监听器中执行此操作,仅使用this不起作用,必须使用ThisActivityClassName.this来获取当前活动的上下文。

0
0 Comments

问题的原因是在使用Android 2.1版本的API Level 7时,调用ProgressDialog.show()方法时会崩溃,并且使用getApplicationContext()作为参数时会导致崩溃。解决方法是使用this关键字作为参数,或者在使用ActivityGroup时使用getParent()方法代替getApplicationContext()。

在解决这个问题的过程中,有用户提到了使用this代替getApplicationContext()的解决方法。另外,还有用户提到在使用ActivityGroup时只能使用getParent()方法来解决这个错误。

尽管有用户认为this和getApplicationContext()是相同的,但是这个解决方法对于开发Android 2.1版本应用程序仍然非常有用。

0