2

I'm developing a phonegap based application, and I also need to call javascript from Java native code, and vice versa

So I added a JavascriptInterface to the droidGap activity (appView.addJavascriptInterface). But each time I call javascript from java, with loadUrl("javascript:alert('Hello')"), an error is raised some seconds after :

/PhoneGapLog( 2839): file:///android_asset/phonegap.js: Line 930 : JSCallback Error:                   
 Request failed.
 I/Web Console( 2839): JSCallback Error: Request failed. at         
 file:///android_asset/phonegap.js:930

And then, another few seconds later, the app crashs, with

E/WindowManager( 2839): Activity com.package.act has leaked                               
window com.android.internal.policy.impl.PhoneWindow$DecorView@2afbfb08 that was      
originally added here
E/WindowManager( 2839): android.view.WindowLeaked: Activity 
com.package.act has leaked window      
com.android.internal.policy.impl.PhoneWindow$DecorView@2afbfb08 that was originally added here
E/WindowManager( 2839):         at android.view.ViewRoot.<init>(ViewRoot.java:265)
E/WindowManager( 2839):         at   android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
E/WindowManager( 2839):         at          android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/WindowManager( 2839):         at android.view.Window$LocalWindowManager.addView(Window.java:424)
E/WindowManager( 2839):         at android.app.Dialog.show(Dialog.java:241)
E/WindowManager( 2839):         at android.app.AlertDialog$Builder.show(AlertDialog.java:816)
E/WindowManager( 2839):         at com.phonegap.DroidGap$6.run(DroidGap.java:1483)
E/WindowManager( 2839):         at android.os.Handler.handleCallback(Handler.java:587)  
E/WindowManager( 2839):         at android.os.Handler.dispatchMessage(Handler.java:92)
E/WindowManager( 2839):         at android.os.Looper.loop(Looper.java:123)
E/WindowManager( 2839):         at android.app.ActivityThread.main(ActivityThread.java:3701)
E/WindowManager( 2839):         at java.lang.reflect.Method.invokeNative(Native Method)
E/WindowManager( 2839):         at java.lang.reflect.Method.invoke(Method.java:507)
E/WindowManager( 2839):         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
E/WindowManager( 2839):         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624) 
E/WindowManager( 2839):         at dalvik.system.NativeStart.main(Native Method)

Here is my code :

public class Bukkett extends DroidGap {

private JavascriptInterface itf;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.init();

    itf = new JavascriptInterface();
    appView.addJavascriptInterface(itf, "Interface");

    this.setIntegerProperty("loadUrlTimeoutValue", 70000);
    super.loadUrl("file:///android_asset/html/index.html");
}

public class JavascriptInterface {
    public void sayHello() {
        loadUrl("javascript:alert('hello');");      
         }
    }
}

In my .js file, I just call

 if (window.Interface)
         window.Interface.sayHello();

The alert message is well displayed, but the app crashs after that.

Janusz
  • 187,060
  • 113
  • 301
  • 369
Stéphane Piette
  • 5,341
  • 6
  • 34
  • 50

2 Answers2

2

if you need to call Java code that you've written from JavaScript you should write a PhoneGap Android plugin:

http://wiki.phonegap.com/w/page/36753494/How%20to%20Create%20a%20PhoneGap%20Plugin%20for%20Android

We've dealt with a lot of the issues that arise in communication between JS to Java and back again. From your Android plugin you can always call sendJavascript() in order to call your JavaScript directly but in most cases you are better off returning a PluginResult.

Simon MacDonald
  • 23,253
  • 5
  • 58
  • 74
0

sendJavaScript is preferable to loadURL , as it won't cause a layout refresh

dijipiji
  • 3,063
  • 1
  • 26
  • 21