如何为javascript接口配置proguard?

Posted

技术标签:

【中文标题】如何为javascript接口配置proguard?【英文标题】:How to configure proguard for javascript interface? 【发布时间】:2013-07-11 20:34:54 【问题描述】:

我已经实现了一个使用 javascriptInterface 的 Webview。它在不混淆时工作正常,但一旦 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>;

有人知道可能出了什么问题吗? 提前致谢

【问题讨论】:

不知道为什么我在 android Studio 4.1.2 中使用默认的 proguard-rule.pro 文件(似乎没有设置任何内容),并且在使用 minifyEnabled=true 构建之后一切正常。 【参考方案1】:

如果不包含拼写错误,您的两种配置都可以正常工作:

ProGuard 需要完全限定的名称:

NonObfuscateable -> com.project.NonObfuscateable

编译的类使用'$'作为内部类的分隔符:

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

在控制台日志中,ProGuard 会打印出有关此类可疑拼写错误的注释。

保留带注释的 Javascript 接口方法的更通用的解决方案:

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

【讨论】:

对于较新的 ProGuard,我们应该使用 -keepclassmembers,allowoptimization,对吧?【参考方案2】:

就我而言,仅工作代码:

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

    
    ...

【讨论】:

【参考方案3】:

如果你使用混淆,除了Eric Lafortune's answer你还需要:

-keepattributes JavascriptInterface

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

【讨论】:

确实,根据@Eric Lafortune 在错误报告中的声明,“ProGuard 目前不知道任何注释的含义”。真不幸……sourceforge.net/p/proguard/bugs/491

以上是关于如何为javascript接口配置proguard?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Android 升级 ProGuard?

如何为 Amazon IAP 设置 ProGuard?

如何为Amazon IAP设置ProGuard?

如何为 Jackson JSON 处理器设置 PROGUARD?

如何为android数据绑定点击监听器编写proguard规则?

Android Proguard Javascript接口失败