6

使用 proguard 混淆后我的项目因 javascriptinterface 而失败

这是有关proguard配置的一些建议的链接,但在我的情况下它不起作用

http://groups.google.com/group/android-developers/browse_thread/thread/f889e846fbf7ec3f?pli=1

因此,来自 Javascript 的调用松散绑定到相关的 Java 方法

我的proguard配置

-keep public class com.trans_code.android.JavascriptCallback 
-keep public class * implements com.trans_code.android.JavascriptCallback 
-keepclassmembers class * implements com.trans_code.android.JavascriptCallback { 
    <methods>; 
} 
-keepclassmembers class * implements JavascriptCallback { 
    void on*(***);
} 
-keep public class com.trans_code.** {
  public protected *;
}

-keepclasseswithmembernames class com.MyActivity$JavascriptInterface

-keepclasseswithmembernames class com.MyActivity$JavascriptInterface {
    public protected *;
}

如果有人知道如何配置 proguard 让它过滤掉对我有很大帮助的相关方法和类

4

4 回答 4

8

来自该原始线程的类名特定于该用户 Java 类,而不是所有 javascript 接口的通用名称。您实现的 javascript 接口只是一个简单的基类。

您需要更改它们以匹配您的接口类的名称。

例如,基于原始线程中的示例,示例代码 WebViewDemo 的正确配置将是:

-keep public class com.google.android.webviewdemo.WebViewDemo.DemoJavaScriptInterface
-keep public class * implements com.google.android.webviewdemo.WebViewDemo.DemoJavaScriptInterface 
-keepclassmembers class * implements com.google.android.webviewdemo.WebViewDemo.DemoJavaScriptInterface { 
    <methods>; 
} 

由于绑定的工作方式,真正需要做的就是防止将从 javascript 调用的内部方法的名称混淆,但保持类名不混淆并没有什么坏处。

于 2011-03-18T20:31:02.207 回答
2

在我的项目中,javascript 接口是一个内部类。所以现在的答案对我不起作用。你需要$在类之间使用。如果您的接口是内部类,请使用此代码

-keep public class com.myapp.MyActivity$MyJavaScriptInterface
-keepclassmembers class com.myapp.MyActivity$MyJavaScriptInterface {
   public *;
}
-keep public class * implements com.myapp.MyActivity$MyJavaScriptInterface

对于 API17+,添加以下行。否则您的代码将无法在 Android 4.2+ 中运行

-keepattributes JavascriptInterface

类似的问题:
Android Proguard Javascript Interface Fail
Javascript interface not working with android 4.2

于 2013-12-07T20:16:27.923 回答
2

这对我来说已经足够了:

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

它还有一个额外的好处,就是可以与您曾经创建的任何类一起用作 Javascript 接口。

它是如何工作的:它使所有标记@JavascriptInterface为的方法都保留其原始名称。它不会自动保留该类,但是由于您必须在代码中实例化该类才能使用它,所以这不是问题。

关于 trante 回答中关于在 API 17+ 上保留注释本身的注释:我在 KitKat 上进行了测试并且它有效,所以它似乎也得到了照顾。

于 2014-08-01T16:36:40.670 回答
1

我这样解决了这个问题:

-keep public class com.myapp.JavaScriptInterface 
-keepclassmembers class com.myapp.JavaScriptInterface { 
    <fields>;
    <methods>;
}

JavaScriptInterface 是我的应用程序中的一个类(不是接口)。这就是为什么我没有使用这部分:

* implements.

于 2012-08-23T17:48:21.507 回答