Как настроить 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>;
}
Есть ли у кого-нибудь представление о том, что может быть неправильным?
Спасибо заранее
Ответы
Ответ 1
Обе ваши конфигурации могли бы работать, если они не содержали опечаток:
-
Для ProGuard требуются полные имена:
NonObfuscateable
→ com.project.NonObfuscateable
-
Скомпилированные классы используют '$' как разделитель для внутренних классов:
com.project.Activity_Webview.JavaScriptInterface
→ com.project.Activity_Webview$JavaScriptInterface
В журнале консоли ProGuard выводит заметки о таких подозрительных опечатках.
Более общее решение для хранения аннотированных методов интерфейса Javascript:
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
Ответ 2
Если вы используете obfuscation, в дополнение к Eric Lafortune answer, вам также нужно:
-keepattributes JavascriptInterface
http://proguard.sourceforge.net/manual/usage.html#obfuscationoptions
Ответ 3
В моем случае работает только код:
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() {
...
}
}
...
}