Android proguard Javascript Interface problem

旧时模样 提交于 2019-12-22 05:19:27

问题


My project after obfuscation with proguard fail with javascriptinterface

Here is the link with some suggestions for proguard configuration but it dosn't work in my case

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

So the calls from Javascript loose binding to the associated Java methods

My proguard configuration regarding that

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

if anyone knows how to configure proguard to have it filter out related methods and classes that will help me a lot


回答1:


The class names from that original thread are specific to that users Java classes, and not generic to to all javascript interfaces. The javascript interface you implement is just a simple base class.

You need to change them to match the name of your interface class.

For example the correct configuration, based on the example from the original thread, for the sample code WebViewDemo would be:

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

Due to the way the bindings work all that really needs to be done is to keep the inner methods that will be called from javascript from having the names obfuscated, but keeping the class name from obfuscation doesn't hurt.




回答2:


In my project javascript interface is an inner class. So present answers doesn't work for me. You need to use $ between classes. Use this code if you interface is an inner class

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

For API17+ add the following line. Else your code won't work in Android 4.2+

-keepattributes JavascriptInterface

Similar questions:
Android Proguard Javascript Interface Fail
Javascript interface not working with android 4.2




回答3:


This was enough for me:

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

It has the added benefit of working with any class you ever make to serve as a Javascript interface.

How it works: It causes all methods tagged with @JavascriptInterface to be kept, with their original name. It will not automatically keep the class, but since you have to instantiate the class in your code to use it, that is not a problem.

Regarding the note in trante's answer about preserving the annotation itself on API 17+: I tested on KitKat and it worked, so it seems that is taken care of as well.




回答4:


I solved this problem so:

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

JavaScriptInterface is a class (not an interface) in my app. That's why I didn't use this part:

* implements.



来源:https://stackoverflow.com/questions/5356560/android-proguard-javascript-interface-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!