2

I have an issue since android 4.2 with proguard.

Basically I use a JavascriptInterface on a webview like this:

public class MyJavascriptInterface {
    public void doSomething() { ... }
}

Now what I do understand is that when proguard obfuscates the code it renames the class name and method name, so it cannot be called from Javascript anymore. That is why I have to add this to the proguard config:

-keepclassmembers class mypackage.MyJavascriptInterface { 
    public void doSomething();
}

When I set the target sdk to 17 (Android 4.2) I have to add the @JavascriptInterface annotation to my Javascript interface method for security reasons:

@JavascriptInterface
public class MyJavascriptInterface {
    public void doSomething() { ... }
}

Now the problem is that this does not work anymore if proguard is enabled (doSomething is not called as if the class is still renamed in the obfuscation step). If I disable proguard the code works fine.

How can I make this work with target sdk 17?

Tim
  • 2,051
  • 17
  • 36
  • For me the javascript interface function are not being called please tell me what should i do??? – Ravi Dec 08 '12 at 06:36
  • Can't say with this description of your problem... You could open a new question and describe your setup in detail, maybe post the relevant android and javascript code ;) – Tim Dec 08 '12 at 11:49
  • http://stackoverflow.com/a/17637530/9636 and http://stackoverflow.com/a/28034176/9636 are more generalized answers. – Heath Borders Jan 19 '15 at 22:03
  • 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:03

3 Answers3

9

I have found the solution, I just have to tell proguard to keep the JavascriptInterface annotation. I added this to my proguard configuration to make it work:

-keepattributes JavascriptInterface
Tim
  • 2,051
  • 17
  • 36
3

To preserve any annotations, you have to add the following to your ProGuard configuration:

-keepattributes *Annotation*

Class files represent the JavascriptInterface annotation as a class attribute of the type "RuntimeAnnotation" with a value "android.webkit.JavascriptInterface".

Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
  • You only need `-keepattributes *Annotation*` if you're using obfuscation. http://proguard.sourceforge.net/manual/usage.html#obfuscationoptions – Heath Borders Jan 19 '15 at 22:02
3

Through looking at the mapping.txt and dump.txt files generated, and a lot of trial and error (I compiled 34 APK files to figure this out), I came up with this working solution:

-keep public class com.yourfullpackagename.Yourapp$JavaScriptInterface
-keepclassmembers class com.yourfullpackagename.Yourapp$JavaScriptInterface {*;}
-keepattributes com.yourfullpackagename.Yourapp$JavaScriptInterface
-keepattributes *Annotation*

(This assume JavaScriptInterface as an inner-class in an Activity called Yourapp in the com.yourfullpackagename namespace. Adjust accordingly for your app.)

Brian Klug
  • 447
  • 1
  • 4
  • 9