Android:ProgressDialog.show() 因 getApplicationContext 崩溃
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1561803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: ProgressDialog.show() crashes with getApplicationContext
提问by Felix
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.access00(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.
任何想法为什么会发生这种情况?我从onCreate
方法中调用它。
采纳答案by Jeremy Logan
Which API version are you using? If I'm right about what the problem is then this was fixed in Android 1.6 (API version 4).
您使用的是哪个 API 版本?如果我对问题所在是正确的,那么这已在 Android 1.6(API 版本 4)中修复。
It looks like the object reference that getApplicationContext()
is returning just points to null. I think you're having a problem similar to one I had in that some of the code in the onCreate()
is being run before the window is actually done being built. This is going to be a hack, but try launching a new Thread in a few hundred milliseconds (IIRC: 300-400 seemed to work for me, but you'll need to tinker) that opens your ProgressDialog and starts anything else you needed (eg. network IO). Something like this:
看起来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
}
回答by Taner
I am using Android version 2.1 with API Level 7. I faced with this (or similar) problem and solved by using this:
我使用的是 API 级别为 7 的 Android 2.1 版。我遇到了这个(或类似的)问题并通过使用这个解决了:
Dialog dialog = new Dialog(this);
instead of this:
而不是这个:
Dialog dialog = new Dialog(getApplicationContext());
Hope this helps :)
希望这可以帮助 :)
回答by wtk
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..
奇怪的是,第一个可以在谷歌教程中找到,人们对此有错误..
回答by alienjazzcat
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)
在 MyApp 中创建一个静态助手(将使用单例)
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
另外,请在此处查看 android 工程师的答案: 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..
现在,我同意,该方法采用 Context 参数而不是 Activity 是没有意义的。
回答by Emile
Having read the above answers i found that for my situation the following fixed the issue.
阅读上述答案后,我发现对于我的情况,以下解决了问题。
This threw the error
这引发了错误
myButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
MyDialogue dialog = new MyDialogue(getApplicationContext());
dialog.show();
}
});
Based on the previous answers that suggested the context was the wrong one, i changed the getApplicationContext() to retrieve the context from the View passed in to the buttons onClick method.
根据之前建议上下文错误的答案,我更改了 getApplicationContext() 以从传递给按钮 onClick 方法的 View 中检索上下文。
myButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
MyDialogue dialog = new MyDialogue(v.getContext());
dialog.show();
}
});
I don't fully understand the workings of Java so i could be wrong, but I'm guessing that for my specific situation the cause could have been related to the fact that the above snippet was defined in an Abstract Activity class; inherited and used by many Activities, perhaps that contributed to the fact that getApplicationContext() doesn't return a valid context?? (Just a guess).
我不完全了解 Java 的工作原理,所以我可能是错的,但我猜测,对于我的特定情况,原因可能与上述代码段是在抽象活动类中定义的事实有关;被许多活动继承和使用,也许这导致了 getApplicationContext() 不返回有效上下文?(只是猜测)。
回答by cipherz
I am creating a map view with itemized overlays. I was creating my itemizedoverlay like this from my mapActivity:
我正在创建一个带有逐项叠加的地图视图。我正在从我的 mapActivity 像这样创建我的 itemizedoverlay:
OCItemizedOverlay currentLocationOverlay = new OCItemizedOverlay(pin,getApplicationContext);
I found that I would get the "android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application" exception when my itemizedoverlay's onTap method was triggered(when the location is tapped on the mapview).
我发现当我的 itemizedoverlay 的 onTap 方法被触发时(当在地图视图上点击位置时),我会得到“android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application”异常。
I found that if I simply passed, 'this' instead of 'getApplicationContext()' to my constructor, the problem went away. This seems to support alienjazzcat's conclusion. weird.
我发现如果我简单地将“this”而不是“getApplicationContext()”传递给我的构造函数,问题就会消失。这似乎支持了alienjazzcat的结论。奇怪的。
回答by salcosand
For Activities shown within TabActivities use getParent()
对于 TabActivities 中显示的活动,请使用getParent()
final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());
instead of
代替
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
回答by jm_java
For Android 2.2
Use this code:
对于 Android 2.2
使用此代码:
//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.
备注:我的自定义对话框是在activity.onCreateDialog(int dialogId)
方法之外创建的。
回答by eyal
Try -
尝试 -
AlertDialog.Builder builder = new AlertDialog.Builder(getParent());
回答by Muz
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.
过与其中使用(兼容性)片段的类似问题的getActivity()
内ProgressDialog.show()
崩溃了。我同意这是因为时机。
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).
尽可能早地放置 mContext 以给它更多时间来获取上下文。仍然不能保证这会起作用,它只是降低了崩溃的可能性。如果它仍然不起作用,您将不得不求助于计时器黑客(这可能会导致其他计时问题,例如稍后关闭对话框)。
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.
当然,如果你可以使用this
or ActivityName.this
,它会更稳定,因为this
已经指向了某些东西。但在某些情况下,比如某些 Fragment 架构,它不是一种选择。