Мгновенный сбой Android WebView с переопределением shouldInterceptRequest

Я получаю удовольствие от Android WebView.

Я использую его, чтобы показать экран входа в систему, а затем перехватить код авторизации в ответ. Должно быть довольно просто...

Мой WebView загружается и отображается абсолютно нормально, если я только переопределяю shouldOverrideUrlLoading, но если я переопределяю (так же, как автозаполнение Android Studio):

override fun shouldInterceptRequest(
    view: WebView?,
    request: WebResourceRequest?
): WebResourceResponse {
    return super.shouldInterceptRequest(view, request)
}

без каких-либо других изменений он сразу же вылетает во время выполнения с родным сбоем

A/хром: [FATAL:jni_android.cc(259)]

с последующим

A/libc: Фатальный сигнал 6 (SIGABRT), код -6 (SI_TKILL) в tid 16220 (TaskSchedulerFo), pid 16175 (eports.internal)

Как ни странно, если я сделаю ответ обнуляемым, WebView снова заработает. Однако добавление чего-либо еще в метод shouldInterceptRequest приводит к падению с той же ошибкой.

Итак, это работает:

override fun shouldInterceptRequest(
    view: WebView?,
    request: WebResourceRequest?
): WebResourceResponse? {
    return super.shouldInterceptRequest(view, request)
}

Но это вылетает с указанным выше сбоем:

override fun shouldInterceptRequest(
    view: WebView?,
    request: WebResourceRequest?
): WebResourceResponse? {
    val url = view?.url
    return super.shouldInterceptRequest(view, request)
}

Это кажется действительно странной проблемой, и мне непонятно, почему добавление присваивания val вообще имеет какое-то значение.

Я исследовал ошибку, и предложения должны были добавить

webView.destroy()

в активности/фрагментах onDestroy/onDestroyView это, к сожалению, не помогает.

Поведение одинаково на устройстве и эмуляторе, а также на Android SDK 22 и 28.

Кто-нибудь видел что-нибудь подобное раньше? Я чувствую, что, вероятно, упускаю что-то очевидное.

На случай, если это будет полезно для всех, я также сгенерировал микродамп Breakpad, он слишком велик, чтобы публиковать этот вопрос. Но дайте мне знать, может ли это или его подмножество помочь в диагностике!


person Flint    schedule 16.07.2018    source источник
comment
Это происходит и со мной.   -  person Erik    schedule 16.07.2018
comment
Хотел бы я сказать, что знаю, что случилось. В моем случае я просто регистрировал URL. Оба метода, один со строкой и один с веб-ресурсом, вызывают это, если я пытаюсь зарегистрировать URL-адрес   -  person Erik    schedule 16.07.2018


Ответы (2)


Я нашел проблему в своем случае, поэтому решил опубликовать ее здесь для всех, кто находится в аналогичной ситуации.

Сбой Native вызван запуском Javascript в WebView.

WebView запускает JavaScript в фоновом потоке, поэтому все, что касается потока пользовательского интерфейса, приводит к его падению на собственном уровне. Давая очень бесполезный сбой выше.

Причина, по которой назначение val вызывало сбой, заключалось не в назначении val, а в вызове if view?.url, который находится в UIThread.

Решение?

Котлин:

webView?.post{
   // Do your UI work here.
}

Ява:

webView.post(new Runnable(){
    public void run() {
    // Do your UI work here.
    }
})

И не трогайте UIThread иначе внутри переопределенного метода!

person Flint    schedule 17.07.2018
comment
я просто переопределяю метод shouldInterceptRequest и ничего не делаю с его ошибкой броска без какого-либо журнала ошибок - person That's Enam; 10.04.2019

Если вы пишете код Kotlin для реализации WebViewClient, вам следует взглянуть на этот ответ и проверить сигнатуру переопределенного метода Kotlin.

Я столкнулся с тем же исключением во время выполнения и понял, что причина этой проблемы заключается в том, что компилятор Kotlin не выполняет взаимодействие между типом возврата метода Java и типом возврата метода Kotlin.

Сигнатура метода кода Java:

    public WebResourceResponse shouldInterceptRequest(WebView view, String url)

которые взаимодействуют с Kotlin путем автоматического завершения методов переопределения, как:

    override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse

Тип возврата метода Kotlin отсутствует ?.
Вам нужно добавить ? к WebResourceResponse, например,

    override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse?
person saiday    schedule 08.08.2019