39

I use in my project a piece of code as described here

http://lexandera.com/2009/01/extracting-html-from-a-webview/

I create the .apk file, install it on my device and it correctly works. If I try to use the obfuscation with proguard the project fails, the method showHTML(String html) of MyJavaScriptInterface is not reached.

My proguard configuration regarding that

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

according to this this answer Android proguard Javascript Interface problem.

SOLVED.

As Eric suggested, I changed the Proguard configuration file like this:

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

Now my project works perfectly.

For API 17+ you also need to preserve the @JavascriptInterface annotations:

-keepattributes JavascriptInterface

http://developer.android.com/reference/android/webkit/JavascriptInterface.html

PEHLAJ
  • 9,980
  • 9
  • 41
  • 53
Denis
  • 423
  • 1
  • 5
  • 9
  • Also -keepatributtes InnerClasses has to be added otherwise ProGuard obfuscates the name of innerclass and $ doenst apply. At least this didnt work for me until I've kept this attribute. – klemzy Jun 03 '14 at 09:55
  • `-keepattributes` only applies when you're using obfuscation. http://proguard.sourceforge.net/manual/usage.html#obfuscationoptions – Heath Borders Jan 19 '15 at 21:55
  • 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 21:59
  • http://stackoverflow.com/a/17637530/9636 and http://stackoverflow.com/a/28034176/9636 are more generalized answers. – Heath Borders Jan 19 '15 at 21:59
  • Adding `-keepattributes JavascriptInterface` doesn't works for me. I added `-keepattributes *Annotation*` to make my JavaScript works in release APK. – Nishant Dec 15 '15 at 05:45

4 Answers4

33

If MyJavaScriptInterface is an inner class of MyClass, ProGuard expects a fully qualified name com.mypackage.MyClass$MyJavaScriptInterface. The naming convention with $ is used in the compiled class files on which ProGuard operates. Note that ProGuard mentions class names in the configuration that it can't find in the input jar, suggesting that these names may have been misspelled.

Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
  • Hi Eric,I tried to modify Proguard configuration according to your suggestion, but the problem persists. Files generated by Proguard could help me to understand the problem? – Denis Jun 08 '11 at 08:52
  • Is the class MyJavaScriptInterface present in the processed code? Is the method showHTML present? You can check this with javap (on java class files) or dexdump (on Android dex files). The ProGuard documentation at Sourceforge contains an extensive example for Android, among other examples. – Eric Lafortune Jun 08 '11 at 21:41
  • 3
    Hi Eric, I solved the problem. I made an error in Proguard configuration file. I wrote: -keepclassmembers class * implements com.mypackage.MyClass$MyJavaScriptInterface { ; } instead -keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface { ; } Thanks for suppots. – Denis Jun 10 '11 at 08:44
4
    -keepclassmembers class com.mypackage.MyClass$JavaScriptInterface {    
public *;
     }

Use only this. It works for me.

Sangoku
  • 41
  • 2
2

Those Who are laze to provide the entire package path.

-keepclassmembers class **.*$PaymentJavaScriptInterface{
public *;
}
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Nantha kumar
  • 153
  • 1
  • 3
  • 8
1

As suggested by edit in question, out of those suggestions, only using

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

with Important -

For API 17+ to preserve @JavascriptInterface annotations:

-keepattributes JavascriptInterface

(Which was stopping my app to work on Marshmallow)

Darpan
  • 5,623
  • 3
  • 48
  • 80