Android Proguard Javascript接口失败

Posted

技术标签:

【中文标题】Android Proguard Javascript接口失败【英文标题】:Android Proguard Javascript Interface Fail 【发布时间】:2011-09-10 10:03:01 【问题描述】:

我在我的项目中使用了这里描述的一段代码

http://lexandera.com/2009/01/extracting-html-from-a-webview/

我创建了 .apk 文件,将其安装在我的设备上,它可以正常工作。如果我尝试使用 proguard 混淆项目失败,MyjavascriptInterface 的方法 showHTML(String html) 没有到达。

我的 proguard 配置

-keep public class com.mypackage.MyClass.MyJavaScriptInterface
-keep public class * implements com.mypackage.MyClass.MyJavaScriptInterface
-keepclassmembers class * implements com.mypackage.MyClass.MyJavaScriptInterface  
    <methods>; 

根据这个答案android proguard Javascript Interface problem。

已解决。

按照 Eric 的建议,我将 Proguard 配置文件更改如下:

-keep public class com.mypackage.MyClass$MyJavaScriptInterface
-keep public class * implements com.mypackage.MyClass$MyJavaScriptInterface
-keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface  
    <methods>; 

现在我的项目完美运行。

对于 API 17+,您还需要保留 @JavascriptInterface 注释:

-keepattributes JavascriptInterface

http://developer.android.com/reference/android/webkit/JavascriptInterface.html

【问题讨论】:

还必须添加 -keepatributes InnerClasses,否则 ProGuard 会混淆内部类的名称并且 $ 不适用。至少在我保留此属性之前,这对我不起作用。 -keepattributes 仅在您使用混淆时适用。 proguard.sourceforge.net/manual/usage.html#obfuscationoptions How to configure proguard for javascript interface?的可能重复 ***.com/a/17637530/9636 和 ***.com/a/28034176/9636 是更通用的答案。 添加 -keepattributes JavascriptInterface 对我不起作用。我添加了-keepattributes *Annotation* 以使我的 JavaScript 在发布 APK 中工作。 【参考方案1】:

如果 MyJavaScriptInterface 是 MyClass 的内部类,ProGuard 需要一个完全限定名称 com.mypackage.MyClass$MyJavaScriptInterface$ 的命名约定用于 ProGuard 运行的编译类文件。请注意,ProGuard 在配置中提到了在输入 jar 中找不到的类名,这表明这些名称可能拼写错误。

【讨论】:

您好 Eric,我尝试根据您的建议修改 Proguard 配置,但问题仍然存在。 Proguard 生成的文件可以帮助我理解问题吗? 处理后的代码中是否存在 MyJavaScriptInterface 类?方法 showHTML 存在吗?您可以使用 javap(在 java 类文件上)或 dexdump(在 Android dex 文件上)进行检查。 Sourceforge 的 ProGuard 文档包含一个广泛的 Android 示例以及其他示例。 嗨,埃里克,我解决了这个问题。我在 Proguard 配置文件中出错。我写道:-keepclassmembers class * implements com.mypackage.MyClass$MyJavaScriptInterface ; 而不是 -keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface ; 感谢您的支持。【参考方案2】:
    -keepclassmembers class com.mypackage.MyClass$JavaScriptInterface     
public *;
     

只使用这个。它对我有用。

【讨论】:

那些懒得输入整个包的人。 \n -keepclassmembers 类 **.*$JavaScriptInterface public *; 【参考方案3】:

那些懒得提供整个包路径的人。

-keepclassmembers class **.*$PaymentJavaScriptInterface
public *;

【讨论】:

【参考方案4】:

正如相关编辑所建议的那样, 从这些建议中, 只使用

-keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface public *;

重要 -

对于 API 17+,保留 @JavascriptInterface 注释:

-keepattributes JavascriptInterface

(这阻止了我的应用程序在 Marshmallow 上运行)

【讨论】:

以上是关于Android Proguard Javascript接口失败的主要内容,如果未能解决你的问题,请参考以下文章

Android 中的 ProGuard 不起作用。(不混淆)

如何为 Android 升级 ProGuard?

启用 PROGUARD - Xamarin.Android

使用 Android 库项目设置 ProGuard

Android - Proguard 和改造 2?

Proguard后Android应用程序崩溃