0

在某些 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。

4

1 回答 1

3

这是因为您试图在活动完成时显示警报对话框。

您可以继承 CordovaChromeClient 并检查 onJsAlert() 上的 activity.isFinishing()

我在 Github 上创建了一个项目来解决这个错误: 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);
    }
}
}
于 2013-01-09T08:59:13.727 回答