29

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

Ikky
  • 2,826
  • 14
  • 47
  • 68
  • Don't know why I use default proguard-rule.pro file (it seems not set anything) in Android Studio 4.1.2 and everything goes right after the build with minifyEnabled=true. – Shrdi Mar 10 '21 at 07:20

3 Answers3

50

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>;
}
Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
5

If you're using obfuscation, in addition to Eric Lafortune's answer you also need:

-keepattributes JavascriptInterface

http://proguard.sourceforge.net/manual/usage.html#obfuscationoptions

Community
  • 1
  • 1
Heath Borders
  • 30,998
  • 16
  • 147
  • 256
  • Indeed, according to a statement by @Eric Lafortune on a bug report, "ProGuard is currently agnostic about the meaning of any annotations". That's unfortunate… http://sourceforge.net/p/proguard/bugs/491/ – Pierre-Luc Paour Apr 01 '15 at 14:54
4

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() {
            ...
        }

    }
    ...
}
Tapa Save
  • 4,769
  • 5
  • 32
  • 54