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のバージョンはわかりませんが、その質問は報告者にあります。

Cordova2.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 に答える