Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure proguard for javascript interface?

I have a implemented a Webview which takes use of JavascriptInterface. It's working fine when not obfuscating, but at once Proguard is active, it does not work. I've looked here at other answers, but i still can't get it working.

Some of the WebView class:

public class Activity_Webview { private WebView webView;      public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         webView = (WebView) findViewById(R.id.webview);         webView.getSettings().setJavaScriptEnabled(true);         webView.addJavascriptInterface(new JavaScriptInterface (), "HTMLOUT");         webView.setWebViewClient(mWebViewClient);     }      public class JavaScriptInterface implements NonObfuscateable{         @JavascriptInterface         public void processHTML(String html) {         handleFinishFromWebView(html);     } } 

What i've tried in Proguard:

-keep public class * implements com.project.NonObfuscateable -keepclassmembers class * implements NonObfuscateable {     public void processHTML(java.lang.String); } 

I've also tried this (when not implementing NonObfuscateable interface:

-keep public class com.project.Activity_Webview.JavaScriptInterface -keep public class * implements com.project.Activity_Webview.JavaScriptInterface -keepclassmembers class * implements com.project.Activity_Webview.JavaScriptInterface {     <fields>;     <methods>; } 

Does anybody have an idea of what could be wrong? Thanks in advance

like image 499
Ikky Avatar asked Jul 13 '13 10:07

Ikky


2 Answers

Both your configurations could have worked if they hadn't contained typos:

  • ProGuard requires fully qualified names:

    NonObfuscateable -> com.project.NonObfuscateable

  • Compiled classes use '$' as a separator for inner classes:

    com.project.Activity_Webview.JavaScriptInterface -> com.project.Activity_Webview$JavaScriptInterface

In the console log, ProGuard prints out notes about such suspected typos.

A more general solution for keeping annotated Javascript interface methods:

-keepclassmembers class * {     @android.webkit.JavascriptInterface <methods>; } 
like image 124
Eric Lafortune Avatar answered Sep 23 '22 02:09

Eric Lafortune


In my case work only code:

proguard.cfg:

-dontwarn  -keepattributes Signature -keepattributes SetJavaScriptEnabled -keepattributes JavascriptInterface -keepattributes InlinedApi -keepattributes SourceFile,LineNumberTable -keepattributes *Annotation*  -keepclassmembers class * {     @android.webkit.JavascriptInterface <methods>; } -keepclassmembers class * {     @android.webkit.JavascriptInterface <methods>; } -keepclassmembers class **.*$MyJavascriptInterface {     *; } -keepclassmembers class **.*$JavaScriptInterface {     *; }  -keep public class **.*$MyJavascriptInteface -keep public class **.*$JavaScriptInterface 

Java code:

@SuppressLint("SetJavaScriptEnabled") public class ActivityWebView extends Activity {     ...     webView.getSettings().setJavaScriptEnabled(true);     webView.addJavascriptInterface(new MyJavascriptInterface(MyActivity.this), "MyJSI");      ....      public class MyJavaScriptInterface {          Context context;          MyJavascriptInterface(Context context) {         this.context = context;         }          @JavascriptInterface         @SuppressWarnings("unused")         public void myjavascriptfunction() {             ...         }      }     ... } 
like image 29
Tapa Save Avatar answered Sep 24 '22 02:09

Tapa Save