2013-11-11 1 views
3

У меня есть приложение, которое сильно использует Android WebView для отображения моего пользовательского HTML-контента. В последнем обновлении Android (4.4/Kit-Kat/SDK-19) был представлен переработанный WebView.Android WebView (4.4) Преобразует пользовательский URL-адрес

Один из моих пользователей с Nexus 5 сообщил о проблеме, когда некоторые ссылки приводят к сбою приложения. Я побежал в эмуляторе 4.4 и отлаживал мой метод WebViewClientshouldOverrideUrlLoading(). На всех ранее протестированных версиях Android (2.2-4.3) URL-адрес String, переданный в метод, имел свой собственный URL-адрес с символами «/». В 4.4 точно такая же ссылка теперь имеет «\» символы вместо них.

Это не имеет никакого смысла для меня. Я загружаю HTML точно так же, поэтому каким-то образом новый WebView превратил все мои косые черты в обратную косую черту.

Почему это делает новый WebView?

ответ

1

Изменения в обработке URL-адресов являются известной проблемой. Подробнее см. В разделе migration guide.

Поведение в этом конкретном случае будет зависеть от схемы вашего базового URL-адреса, от того, что вы описываете Я предполагаю, что схема вашего базового URL-адреса является «http (s): //« в этом случае Chromium WebView выполняет URL normalization.

Возможно, вы захотите использовать URI class для обработки несоответствия между классическим и хромовым WebViews в этом случае.

+0

Первоначально я принял свой собственный ответ, потому что он был прямым ответом на мою проблему, но этот ответ помог мне в нескольких других местах, где у меня были некоторые пользовательские значения href, которые перепутались из-за того, как 4.4 обрабатывал мои пользовательские URL-адреса. Так что спасибо! – Jon

1

Я сделал больше отладки и обнаружил, что у меня на самом деле вопрос был отменен. Оказывается, более старые версии WebView сделали преобразования URL, а не новые.

загружает HTML с форматом похож на это в WebView:

<a href="this\\is\\my\\custom\\path">link</a> 

Я использую двойные назад косую черту в качестве разделителей и разбора позже данными при щелчке ссылки. В более старых версиях WebView он преобразует мои двойные символы обратной косой черты в косые черты. Это было так давно, когда я был в этом коде, я забыл, что я скорректировал свой код, чтобы использовать косые черты, а не обратную косую черту в исходном HTML.

Новая версия WebView оставляет мой заказ URL неповрежденным, давая мне ту же строку, что и мой оригинальный HTML. Так получается старый WebView проблема не новая.

+0

Не могли бы вы мне помочь, http://stackoverflow.com/questions/20582282/uncaught-referenceerror-while-loading-asset-file-on-android-4-4 –

0

, чтобы избежать веб-просмотра ниже 4.4 конвертировать обратную косую черту в обратную косую черту, я просто избегаю своего url, а затем в Java-коде, используя URI.decode, чтобы получить реальный url.That работает для меня.

0

Новый WebView применяет дополнительные ограничения при запросе ресурсов и разрешении ссылок, использующих настраиваемую схему URL. Например, если вы выполняете обратные вызовы, такие как shouldOverrideUrlLoading() или shouldInterceptRequest(), то WebView вызывает их только для действительных URL-адресов.

Если вы используете настраиваемую схему URL или базовый URL-адрес и обратите внимание, что ваше приложение получает меньше вызовов этих обратных вызовов или не загружает ресурсы на Android 4.4, убедитесь, что в запросах указаны допустимые URL-адреса, соответствующие RFC 3986.

Например, новый WebView не может назвать свой метод shouldOverrideUrlLoading() для ссылок, как это:

Показать Профиль Результат пользователь должен щелкнуть такую ​​ссылку можно варьировать:

Если загружен на странице loadData() или loadDataWithBaseURL() с недопустимым или нулевым базовым URL-адресом, вы не получите обратный вызов shouldOverrideUrlLoading() для этого типа ссылки на странице. Примечание. Если вы используете loadDataWithBaseURL(), а базовый URL-адрес недействителен или установлен нуль, все ссылки в загружаемом вами содержимом должны быть абсолютными.

Если вы загрузили страницу, вызвав loadUrl() или указав действительный базовый URL-адрес с помощью loadDataWithBaseURL(), вы получите обратный вызов shouldOverrideUrlLoading() для этого типа ссылки на странице, но URL-адрес, который вы получите, будет по отношению к текущей странице. Например, URL-адрес, который вы получите, будет «http://www.example.com/showProfile» вместо «showProfile». Вместо того, чтобы использовать простую строку в ссылку, как показано выше, вы можете использовать пользовательскую схему, такие как следующие: метод

<a href="example-app:showProfile">Show Profile</a> 

Вы можете обрабатывать этот URL в вашем shouldOverrideUrlLoading(), как это:

// The URL scheme should be non-hierarchical (no trailing slashes) 
    private static final String APP_SCHEME = "example-app:"; 

@Override 
public boolean shouldOverrideUrlLoading(WebView view, String url) { 
    if (url.startsWith(APP_SCHEME)) { 
     urlData = URLDecoder.decode(url.substring(APP_SCHEME.length()), "UTF-8"); 
     respondToData(urlData); 
     return true; 
    } 
    return false; 
} 

Если вы не можете изменить HTML, вы можете использовать loadDataWithBaseURL() и установить базовый URL-адрес, состоящий из пользовательской схемы и допустимого хоста, например «example-app: ///». Например:

webView.loadDataWithBaseURL("example-app://example.co.uk/", HTML_DATA, 
    null, "UTF-8", null); 

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