7

I have a custom Webview in my android project as shown below:

public class MyWebView extends WebView {

    public MyWebView(Context context) {
        super(context);
    }

   public class JsObject {

        @JavascriptInterface
        public void show() {
            //...
        }

        @JavascriptInterface
        public void hide() {
            //....
        }
}

that includes a JavascriptInterface which I use to communicate from the JavaScript side to the Android side.

In the AndroidManifest I had the following

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="16" />

In the project I used proguard which declared:

-keepattributes JavascriptInterface

-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

and everything was working fine.

However when i changed my AndroidManifest to android:targetSdkVersion=18 or 19 and test on devices with 18 and above, proguard seems to somehow mess the JavaScript methods which are not accessible anymore.

If I put back to 16 or anything less than 17 everything works fine. Additionally this happens only with proguard. If I don't use proguard everything works fine even with android:targetSdkVersion=18 or 19. Can anyone help to make it work when targeting in the manifest Android > 17?

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
andreasv
  • 689
  • 3
  • 11
  • 26
  • The `@JavascriptInterface` was introduced in SDK level 17. You would receive compilation errors that the annotation cannot be resolved, and by removing it, Proguard would not locate any matches and remove all methods as well. Are you sure the last paragraph accurately describes your problem? – Paul Lammertsma Jan 21 '14 at 13:59
  • Paul thank you for your reply. Yes I am aware of the introduction of @JavascriptInterface in SDK level 17. I have been using that approach for months and everything was working fine. Only this change android:targetSdkVersion=18 or 19 in the manifest just mess with proguard and javascript interfaces on run time. Proguard compiles fine in all cases, no reported errors or warnings! – andreasv Jan 21 '14 at 14:07
  • @andreasv I have this exact same problem with my javascript interface. The compiled app works fine on below api level 17 devices but not on jelly bean and above. Also I included appbrain sdk in my app and it also gives the warning to check proguard configs. It's as if javascript is off over whole application. Without proguard it works fine. I've spent my whole day and tried each and every solution suggessted on stackoverflow and none of them worked. Have you solved this issue? please help guys! – lightsaber Mar 02 '14 at 12:28
  • @StarWars -keepattributes *Annotation* solved my problem! – andreasv Mar 04 '14 at 09:27
  • @andreasv I already have -keepattribues *Annotation*. But I found the solution, I am using some library which has methods which are not annotated with JavascriptInterface. So now the issue is solved. Thanks! – lightsaber Mar 04 '14 at 10:29
  • http://stackoverflow.com/a/17637530/9636 and http://stackoverflow.com/a/28034176/9636 are more generalized answers. – Heath Borders Jan 19 '15 at 22:02
  • possible duplicate of [How to configure proguard for javascript interface?](http://stackoverflow.com/questions/17629507/how-to-configure-proguard-for-javascript-interface) – Heath Borders Jan 19 '15 at 22:04

3 Answers3

19

I copy my answer from this topic for you: https://stackoverflow.com/a/19994873/1735499

And, if you are using Proguard, remember to add this

-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

-keepattributes JavascriptInterface
-keep public class com.mypackage.MyClass$MyJavaScriptInterface
-keep public class * implements com.mypackage.MyClass$MyJavaScriptInterface
-keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface { 
    <methods>; 
}

If it's still not OK, add this

-keepattributes *Annotation*

Note: your MyJavaScriptInterface must be Public class

Ref#: Android Proguard Javascript Interface Fail

Br,

Frank

Community
  • 1
  • 1
Frank Nguyen
  • 6,493
  • 3
  • 38
  • 37
  • 1
    You need `-keepattributes *JavascriptInterface*` if you're using obfuscation. http://proguard.sourceforge.net/manual/usage.html#obfuscationoptions – Heath Borders Jan 19 '15 at 22:01
6

These 4 lines are usually enough - and no need to make the interface public.

-keepattributes JavascriptInterface
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}
Alexandre G
  • 1,655
  • 20
  • 30
1

In my case, just :

-keepclassmembers class com.mypackage.MyJavaScriptInterface {
  public *;
}

-keepattributes *Annotation*

was enough !

yrt
  • 11
  • 1