Интерфейс JavaScript WebView только кажется, что работает через Android-Studio Instant-Run, но не при компиляции через обычный Gradle
Настройка
У меня есть простой фрагмент, который содержит компонент WebView. Во время инициализации этого фрагмента я регистрирую несколько методов интерфейса JavaScript в своем приложении:
mJavaScriptHooks = new JavaScriptHooks();
...
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(mJavaScriptHooks, "Android");
Мои JavaScript-хуки ничего особенного, и все они объявлены следующим образом:
public class JavaScriptHooks {
@JavascriptInterface
public void someMethod() {
...
}
...
}
Чтобы убедиться, что эти методы не запутаны и не оптимизированы до неузнаваемости, я добавил следующую конфигурацию ProGuard:
-keepattributes JavascriptInterface
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
Эта проблема
Все работает как положено. Веб-страница успешно вызывает методы через предоставленный объект "Android", методы вызываются и выполняют свою соответствующую задачу. Однако это работает только тогда, когда я запускаю приложение, используя APK, созданный с помощью функции мгновенного запуска Android Studio.
Не имеет значения, установлен ли APK через Android Studio или я устанавливаю его через командную строку, используя adb install
Если я скомпилирую свой APK через обычный gradle (или отключу Instant-Run), то интерфейс JavaScript перестает работать.
отладка
Прежде всего, я убедился, что ProGuard отключен. Даже если ProGuard каким-то образом "волшебным образом" включен, моя конфигурация ProGuard должна гарантировать, что мои методы JS останутся одни.
Я также разобрал APK, чтобы убедиться, что методы, предоставляемые через интерфейс JS, не каким-то образом искажены (или удалены). Они не. Кажется, они присутствуют, как заявлено, в файле DEX.
Когда я запускаю APK, сгенерированный с включенным Instant-Run, я могу проверить (через Chrome), что страница, загруженная в WebView, и увидеть, что мой объект "Android" доступен и все методы, которые я показал, есть (и invokable):
> Android
Object
someMethod()
__proto__
Тем не менее, когда я запускаю APK с отключенным Instant-Run (т. Е. Vanilla Gradle), объект "Android" доступен, но ни один из моих методов там не доступен. Это просто пустой объект.
> Android
Object
__proto__
Страница, которую я загружаю в WebView, живет на общедоступном сервере, которым я управляю. В обеих сборках APK загружается одна и та же страница, и методы вызываются одинаково. Кажется, работает только APK, созданный с помощью функции Instant-Run.
Я копался весь день, но не смог найти ничего по-настоящему полезного. Большинство предложений указывают на проблему с конфигурацией ProGuard или на старые ошибки (т. Е. Gingerbread-эры) в WebView.
1 ответ
У меня была такая же проблема раньше, WebView может распознавать методы только в том случае, если он установлен на Android Studio с SDK, версия которого совпадает с версией устройства. после поиска в интернете я нашел это:
Android WebView JavaScript обратные вызовы не работают в APK без Proguard
Вы объявили свои методы JavascriptInterface общедоступными? Я видел, что ваш пример метода общедоступен, но вы не показываете реальный код, может быть, вы забыли об этом в своем реальном коде?