Reputation: 95
On some Android devices, my Cordova-based app crashes around the time I prompt the user if they'd like to receive notifications, which happens on the first app startup. Here's a typical stack trace:
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)
The JavaScript code:
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'
);
Any ideas? I don't know which devices or Android versions are affected, but that question is out there to those who have reported it.
I'm using Cordova 2.2.0.
Upvotes: 0
Views: 2231
Reputation: 1049
This is because you are trying to display alert dialog while the activity is finishing.
You can subclass CordovaChromeClient and check for activity.isFinishing() on onJsAlert()
I have created a project on Github that solves this bug: https://github.com/kruyvanna/CordovaAlertBug_Android
You can see an example below.
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);
}
}
}
Upvotes: 3