Как настроить proguard для интерфейса javascript?

У меня есть реализованный Webview, который использует JavascriptInterface. Работает нормально, когда не запутывает, но сразу Proguard активен, не работает. Я посмотрел здесь на другие ответы, но я все еще не могу заставить его работать.

Некоторые из класса WebView:

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);
    }
}

Что я пробовал в Proguard:

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

Я также попробовал это (когда не реализует интерфейс NonObfuscateable:

-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>;
}

У кого-нибудь есть представление о том, что может быть не так? заранее спасибо

3 ответа

Обе ваши конфигурации могли бы работать, если бы они не содержали опечаток:

  • ProGuard требует полностью определенных имен:

    NonObfuscateable -> com.project.NonObfuscateable

  • Скомпилированные классы используют '$' в качестве разделителя для внутренних классов:

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

В журнале консоли ProGuard выводит заметки о таких предполагаемых опечатках.

Более общее решение для хранения аннотированных методов интерфейса Javascript:

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

Если вы используете обфускацию, в дополнение к ответу Эрика Лафортуна вам также понадобится:

-keepattributes JavascriptInterface

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

В моем случае работает только код:

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-код:

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

    }
    ...
}
Другие вопросы по тегам