WebView shouldOverrideUrlLoading() не вызывается для недопустимых ссылок
В файле HTML есть два типа ссылок:
(1) A normal link like http://www.bbb.com/q?type=normal
(2) A short link like /q?type=short.
Для первого рода просто загрузите URL. Для второго типа я должен добавить его с фиксированным адресом, например http://www.abc.com, перед загрузкой URL.
Я пытаюсь сделать это с переопределением функции shouldOverrideUrlLoading() в WebViewClient. Однако эта функция не вызывается для второго типа ссылки. Я попробовал добавить http://www.abc.com к второму типу ссылок в файле HTML. Затем функция вызывается, когда я нажимаю второй тип ссылки.
Я думаю, что происходит в WebView, прежде всего, проверьте, является ли ссылка действительным URL-адресом. Только если он действителен, будет вызвана функция. Я прав? Как я могу это решить? Спасибо заранее.
contentWebView = new WebView(context);
webViewClient = new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// String not in Logger.
Log.d(TAG, "Here!");
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
context.startActivity(intent);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (hosted) {
contentWebView.setVisibility(VISIBLE);
} else {
summaryTextView.setVisibility(VISIBLE);
articleLinkButton.setVisibility(VISIBLE);
}
progressBar.setVisibility(View.GONE);
}
};
contentWebView.setWebViewClient(webViewClient);
contentWebView.getSettings().setJavaScriptEnabled(true);
contentWebView.loadData(fullString, "text/html", "utf-8");
contentWebView.setVisibility(GONE);
Подробнее об этом:
Я попытался изменить
contentWebView.loadData(fullString, "text/html", "utf-8");
к
contentWebView.loadDataWithBaseURL("http://www.abc.com", fullString, "text/html", "utf-8", null);
Затем функция вызывается.
Если я изменил короткую ссылку на полную ссылку в строке html вручную. Тогда функция также вызывается.
Итак, я думаю, что это, вероятно, происходит: WebView проверяет правильность URL ссылки. Только после того, как URL-адрес будет действительным, вызывается вызов toOverrideUrlLoading().
Ответы
Ответ 1
Вероятно, вы используете KitKat WebView. Это известная проблема (я думаю, она изложена в руководстве по миграции), где URL-адреса, которые не могут быть разрешены по отношению к базовому URL-адресу, удаляются на пол (вы не получите никаких обратных вызовов для них, а также не должны использоватьOverrideUrlLoading или onPageStarted).
Проблема заключается в том, что ваш базовый URL-адрес является URL-адресом данных, поэтому вы пытаетесь разрешить "/q? type = short" в отношении "data: text/html,...", что не имеет особого смысла и поэтому вся попытка навигации по URL-адресу игнорируется.
Это было другим для предварительного KK WebView, который использовал KURL вместо GURL для обработки URL. GURL обычно более строгий (и более безопасный), чем KURL, что является причиной некоторой несовместимости между двумя версиями WebView.
Ответ 2
решение, которое работало для меня, состояло в том, чтобы использовать loadDataWithBaseURL с недопустимым baseUrl и обнаружить это и удалить его и заменить на "http://" во время setWebViewClient
public class MyActivity
extends Activity
{
private static final String badurl = "http://myappname.invalid/";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
...
WebView wv = ((WebView)findViewById(R.id.webview));
WebSettings settings = wv.getSettings();
settings.setJavaScriptEnabled(false);
settings.setSupportMultipleWindows(true);
wv.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)
{
handleUrlview.getHitTestResult().getExtra());
return true;
}
});
wv.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
handleUrl(url);
return true;
}
});
wv.loadDataWithBaseURL(badurl,text,"text/html","utf-8",null);
}
private void handleUrl(String url)
{
if (url.startsWith(badurl))
url = "http://"+url.substring(badurl.length());
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
} catch (ActivityNotFoundException e) { }
}
}
Ответ 3
Возможно, попробуйте использовать onPageStarted метод
Ответ 4
я столкнулся с этой проблемой и решил ее, заменив мой html-ответ. В моем html-ответе нет хоста в html-тегах href. Затем я заменил его следующими кодами и теперь работает как шарм:)
String htmlString = AppCache.homePageResponse.showcaase.replace("href=\"/", "href=\"" + "evidea://" );
Ответ 5
Я обнаружил, что если ваша страница работает в iframe, нажав на внешний (http://www...), ссылки НЕ запускают shouldOverrideUrlLoading()!
См. shouldOverrideUrlLoading() не вызывается для внешних ссылок из iframe
Ответ 6
Попробуйте это
private static WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //should be activity_main
webView = (WebView) findViewById(R.id.web);
webView.setWebViewClient(new webviewclient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://www.yahoo.com");
}
public class webviewclient extends WebViewClient{
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.toString());
return true;
}