Android:ProgressDialog.show()在调用getApplicationContext时崩溃

111

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

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方法中调用它的。

如果您正在使用Fragment,请参考https://dev59.com/-GAf5IYBdhLWcg3wSQ8z。 - Yeo
18个回答

2

我曾经遇到过类似的问题,与“兼容性”Fragments有关。在ProgressDialog.show()中使用getActivity()会导致崩溃。我同意这是因为时间问题。

一个可能的解决方案:

mContext = getApplicationContext();

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

使用

的替代方案
mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);

尽可能早地放置mContext,以便它有更多时间获取上下文。这仍然不能保证其有效性,但可以降低崩溃的可能性。如果仍无法正常工作,则必须采用计时器hack(可能会导致其他时间问题,例如稍后取消对话框)。
当然,如果您可以使用“this”或“ActivityName.this”,那么更稳定,因为“this”已经指向某个东西。但在某些情况下,比如某些片段架构中,这不是一个选择。

2
(供将来参考)
我认为这是因为应用程序上下文和活动上下文存在差异,可以在这里解释: http://www.doubleencore.com/2013/06/context/ 这意味着我们不能使用应用程序上下文显示对话框。就是这样。

抱歉,如果我想基于应用程序上下文显示HUD,该怎么做? - famfamfam

1
如果您在片段中调用ProgressDialog.show(),将mContext转换为Activity对我很有帮助。
     ProgressDialog pd = new ProgressDialog((Activity) mContext);

1
我为了解决这个问题所做的是创建一个基类,用于存储全局数据,然后所有我的活动都继承该基类。在第一个活动中,我将上下文保存在我的基类的变量中,如下所示:
基类
public static Context myucontext; 

从基类派生的第一个活动

mycontext = this

然后我在创建对话框时使用mycontext而不是getApplicationContext。

AlertDialog alertDialog = new AlertDialog.Builder(mycontext).create();

很遗憾,这个解决方案没有得到更多的赞。在这里提出的所有可能的解决方案中,这是唯一在AsyncTask中为我工作的东西。 - ckn

1
这是一个常见的问题。 使用this代替getApplicationContext() 这样应该就能解决你的问题了。

0

如果你在groupActivity遇到问题,请不要使用这个。 PARENT是从Parent ActivityGroup中静态获取的。

final AlertDialog.Builder builder = new AlertDialog.Builder(GroupActivityParent.PARENT);

而不是

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

0

我已经为异常抛出在当前活动视图上实现了警报对话框。每当我像这样给出时

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

给定相同的窗口异常。我编写了一个在onCreate()之外弹出警报的代码。所以我简单地在onCreate()方法中的setContentView()语句后使用了context = this;。将context变量作为全局变量,如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


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接