Интерфейс 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 общедоступными? Я видел, что ваш пример метода общедоступен, но вы не показываете реальный код, может быть, вы забыли об этом в своем реальном коде?

Другие вопросы по тегам