272

setWebViewClientsetWebChromeClient在 Android 中的区别是什么?

4

4 回答 4

163

源代码

// Instance of WebViewClient that is the client callback.
private volatile WebViewClient mWebViewClient;
// Instance of WebChromeClient for handling all chrome functions.
private volatile WebChromeClient mWebChromeClient;

// SOME OTHER SUTFFF.......

/**
 * Set the WebViewClient.
 * @param client An implementation of WebViewClient.
 */
public void setWebViewClient(WebViewClient client) {
    mWebViewClient = client;
}

/**
 * Set the WebChromeClient.
 * @param client An implementation of WebChromeClient.
 */
public void setWebChromeClient(WebChromeClient client) {
    mWebChromeClient = client;
}

使用 WebChromeClient 可以让您处理 Javascript 对话框、网站图标、标题和进度。看一下这个例子:Adding alert() support to a WebView

乍一看,WebViewClientWebChromeClient的区别太多了。但是,基本上:如果您正在开发一个不需要太多功能但呈现 HTML 的 WebView,您可以只使用WebViewClient. 另一方面,如果你想(例如)加载你正在渲染的页面的图标,你应该使用一个WebChromeClient对象并覆盖onReceivedIcon(WebView view, Bitmap icon).

大多数时候,如果你不想担心这些事情......你可以这样做:

webView= (WebView) findViewById(R.id.webview); 
webView.setWebChromeClient(new WebChromeClient()); 
webView.setWebViewClient(new WebViewClient()); 
webView.getSettings().setJavaScriptEnabled(true); 
webView.loadUrl(url); 

并且您的 WebView 将(理论上)实现所有功能(作为 android 本机浏览器)。

于 2010-05-14T16:12:53.857 回答
133

我觉得这个问题需要更多细节。我的回答灵感来自 Android Programming, The Big Nerd Ranch Guide (2nd edition)。

默认情况下,JavaScript 在 WebView 中处于关闭状态。您并不总是需要打开它,但对于某些应用程序,可能确实需要它。

加载 URL 必须在配置 WebView 之后完成,所以你最后才这样做。在此之前,您通过调用getSettings()获取 WebSettings 实例并调用WebSettings.setJavaScriptEnabled(true). WebSettings 是您可以修改 WebView 的三种方法中的第一种。它具有您可以设置的各种属性,例如用户代理字符串和文本大小。

之后,您配置您的 WebViewClient。WebViewClient 是一个事件接口。通过提供您自己的 WebViewClient 实现,您可以响应呈现事件。例如,您可以检测渲染器何时开始从特定 URL 加载图像或决定是否重新向服务器提交 POST 请求。

WebViewClient有许多可以覆盖的方法,其中大部分您不会处理。但是,您确实需要替换默认 WebViewClient 的shouldOverrideUrlLoading(WebView, String). 此方法确定在 WebView 中加载新 URL 时会发生什么,例如按下链接。如果你返回 true,你是在说,“不要处理这个 URL,我自己处理它。” 如果你返回 false,你是在说,“继续加载这个 URL,WebView,我没有用它做任何事情。”</p>

默认实现会使用 URL 触发隐式意图,就像您之前所做的那样。不过,现在这将是一个严重的问题。一些 Web 应用程序所做的第一件事就是将您重定向到网站的移动版本。使用默认的 WebViewClient,这意味着您会立即被发送到用户的默认 Web 浏览器。这正是您要避免的。修复很简单——只需覆盖默认实现并返回 false。

使用 WebChromeClient 进行修饰 由于您正在花时间创建自己的 WebView,让我们通过添加进度条并使用加载页面的标题更新工具栏的副标题来对其进行修饰。

要连接 ProgressBar,您将使用 WebView 上的第二个回调:WebChromeClient

WebViewClient 是响应渲染事件的接口;WebChromeClient 是一个事件接口,用于响应应该更改浏览器周围 chrome 元素的事件。这包括 JavaScript 警报、网站图标,当然还有加载进度和当前页面标题的更新。

把它挂在onCreateView(…). 使用 WebChromeClient 来美化进度更新和标题更新每个都有自己的回调方法, onProgressChanged(WebView, int)并且onReceivedTitle(WebView, String). 您收到的进度onProgressChanged(WebView, int)是从 0 到 100 的整数。如果是 100,则您知道页面已完成加载,因此您可以通过将 ProgressBar 的可见性设置为 来隐藏它View.GONE

免责声明:此信息取自 Android 编程:经作者许可的大书呆子牧场指南。有关本书的更多信息或购买副本,请访问 bignerdranch.com。

于 2016-12-25T19:36:28.493 回答
5

如果你想从网页记录错误,你应该使用WebChromeClient并覆盖它onConsoleMessage

webView.settings.apply {
    javaScriptEnabled = true
    javaScriptCanOpenWindowsAutomatically = true
    domStorageEnabled = true
}
webView.webViewClient = WebViewClient()
webView.webChromeClient = MyWebChromeClient()

private class MyWebChromeClient : WebChromeClient() {
    override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
        Timber.d("${consoleMessage.message()}")
        Timber.d("${consoleMessage.lineNumber()} ${consoleMessage.sourceId()}")
        return super.onConsoleMessage(consoleMessage)
    }
}
于 2020-08-26T09:15:19.250 回答
3

WebViewClient提供了以下回调方法,您可以使用这些方法来干预如何WebView转换到下一个内容

void doUpdateVisitedHistory (WebView view, String url, boolean isReload)
void onFormResubmission (WebView view, Message dontResend, Message resend)
void onLoadResource (WebView view, String url)
void onPageCommitVisible (WebView view, String url)
void onPageFinished (WebView view, String url)
void onPageStarted (WebView view, String url, Bitmap favicon)
void onReceivedClientCertRequest (WebView view, ClientCertRequest request)
void onReceivedError (WebView view, int errorCode, String description, String failingUrl)
void onReceivedError (WebView view, WebResourceRequest request, WebResourceError error)
void onReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, String host, String realm)
void onReceivedHttpError (WebView view, WebResourceRequest request, WebResourceResponse errorResponse)
void onReceivedLoginRequest (WebView view, String realm, String account, String args)
void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error)
boolean onRenderProcessGone (WebView view, RenderProcessGoneDetail detail)
void onSafeBrowsingHit (WebView view, WebResourceRequest request, int threatType, SafeBrowsingResponse callback)
void onScaleChanged (WebView view, float oldScale, float newScale)
void onTooManyRedirects (WebView view, Message cancelMsg, Message continueMsg)
void onUnhandledKeyEvent (WebView view, KeyEvent event)
WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request)
WebResourceResponse shouldInterceptRequest (WebView view, String url)
boolean shouldOverrideKeyEvent (WebView view, KeyEvent event)
boolean shouldOverrideUrlLoading (WebView view, WebResourceRequest request)
boolean shouldOverrideUrlLoading (WebView view, String url)

WebChromeClient提供以下回调方法,您可以使用这些Activity回调方法Fragment更新.WebView

Bitmap getDefaultVideoPoster ()
View getVideoLoadingProgressView ()
void getVisitedHistory (ValueCallback<String[]> callback)
void onCloseWindow (WebView window)
boolean onConsoleMessage (ConsoleMessage consoleMessage)
void onConsoleMessage (String message, int lineNumber, String sourceID)
boolean onCreateWindow (WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)
void onExceededDatabaseQuota (String url, String databaseIdentifier, long quota, long estimatedDatabaseSize, long totalQuota, WebStorage.QuotaUpdater quotaUpdater)
void onGeolocationPermissionsHidePrompt ()
void onGeolocationPermissionsShowPrompt (String origin, GeolocationPermissions.Callback callback)
void onHideCustomView ()
boolean onJsAlert (WebView view, String url, String message, JsResult result)
boolean onJsBeforeUnload (WebView view, String url, String message, JsResult result)
boolean onJsConfirm (WebView view, String url, String message, JsResult result)
boolean onJsPrompt (WebView view, String url, String message, String defaultValue, JsPromptResult result)
boolean onJsTimeout ()
void onPermissionRequest (PermissionRequest request)
void onPermissionRequestCanceled (PermissionRequest request)
void onProgressChanged (WebView view, int newProgress)
void onReachedMaxAppCacheSize (long requiredStorage, long quota, WebStorage.QuotaUpdater quotaUpdater)
void onReceivedIcon (WebView view, Bitmap icon)
void onReceivedTitle (WebView view, String title)
void onReceivedTouchIconUrl (WebView view, String url, boolean precomposed)
void onRequestFocus (WebView view)
void onShowCustomView (View view, int requestedOrientation, WebChromeClient.CustomViewCallback callback)
void onShowCustomView (View view, WebChromeClient.CustomViewCallback callback)
boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
于 2020-08-30T08:49:05.463 回答