在某些Android设备上,基于Cordova的应用程序崩溃的时候我会提示用户,如果他们想要收到通知,这会在第一个应用启动时发生。这是典型的堆栈跟踪:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@<i>[eight hex digits]</i> is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:535)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.app.Dialog.show(Dialog.java:241)
at android.app.AlertDialog$Builder.show(AlertDialog.java:802)
at org.apache.cordova.Notification$2.run(Notification.java:245)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3806)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
JavaScript代码:
navigator.notification.confirm(
'Do you wish to receive push notifications?',
function(btnIndex) {
if (btnIndex == 1) {
push.enablePush();
localStorage.pushAsked = true;
} else {
push.disablePush();
localStorage.pushAsked = true;
}
},
'Push Notifications',
'Yes,No'
);
有什么想法吗?我不知道哪些设备或Android版本会受到影响,但这个问题已经出现在报告它的人身上。
我正在使用Cordova 2.2.0。
答案 0 :(得分:3)
这是因为您正在尝试在活动结束时显示警告对话框。
您可以继承CordovaChromeClient并检查onJsAlert()上的activity.isFinishing()
我在Github上创建了一个解决这个bug的项目: https://github.com/kruyvanna/CordovaAlertBug_Android
您可以在下面看到一个示例。
class CordovaOnJsAlertBug extends DroidGap{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.loadUrl("file:///android_asset/www/index.html");
}
@Override
public void init() {
Log.e(TAG, "init()");
CordovaWebView webView = new CordovaWebView(CordovaOnJsAlertBug.this);
CordovaWebViewClient webViewClient;
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
{
webViewClient = new CordovaWebViewClient(this, webView);
}
else
{
webViewClient = new IceCreamCordovaWebViewClient(this, webView);
}
this.init(webView, webViewClient, new MyCordovaChromeClient(this, webView));
}
private class MyCordovaChromeClient extends CordovaChromeClient{
private CordovaInterface cordova;
public MyCordovaChromeClient(CordovaInterface ctx, CordovaWebView app) {
super(ctx, app);
this.cordova = ctx;
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
if(cordova.getActivity().isFinishing()){
Log.w(TAG, "Trying to alert while activity is finishing!! -> ignore");
result.cancel();
return true;
}
return super.onJsAlert(view, url, message, result);
}
}
}