Проблема с интерфейсом Javascript для Android - PullRequest
6 голосов
/ 18 марта 2011

Мой проект после обфускации с 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 ]

8 голосов
/ 18 марта 2011

Имена классов из этого исходного потока специфичны для классов 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, иметь именазапутывает, но удержание имени класса от запутывания не повредит.

2 голосов
/ 01 августа 2014

Мне этого было достаточно:

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

Он имеет дополнительное преимущество работы с любым классом, который вы когда-либо создавали, чтобы служить интерфейсом Javascript.

Как это работает: все методы, отмеченные @JavascriptInterface, сохраняются с их исходным именем. Он не будет автоматически хранить класс, но поскольку для его использования вам нужно создать экземпляр класса в своем коде, это не проблема.

Что касается примечания в ответе транта о сохранении самой аннотации на API 17+: я тестировал на KitKat, и он работал, так что, похоже, об этом тоже позаботились.

2 голосов
/ 08 декабря 2013

В моем проекте интерфейс 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

Подобные вопросы:
Ошибка интерфейса Javascript для Android Proguard
Интерфейс Javascript не работает с Android 4.2

1 голос
/ 23 августа 2012

Я решил эту проблему так:

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

JavaScriptInterface - это класс (а не интерфейс) в моем приложении. Вот почему я не использовал эту часть:

* implements.

...