Android中的setWebViewClient和setWebChromeClient有什么区别?


当前回答

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)

其他回答

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)

如果你想从web页面记录错误,你应该使用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)
    }
}

我觉得这个问题需要再详细一点。我的答案来自于Android Programming, the Big Nerd Ranch Guide(第二版)。

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

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

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

WebViewClient has many methods you can override, most of which you will not deal with. However, you do need to replace the default WebViewClient’s implementation of shouldOverrideUrlLoading(WebView, String). This method determines what will happen when a new URL is loaded in the WebView, like by pressing a link. If you return true, you are saying, “Do not handle this URL, I am handling it myself.” If you return false, you are saying, “Go ahead and load this URL, WebView, I’m not doing anything with it.”

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

使用WebChromeClient来整理一下 由于您正在花时间创建自己的WebView,让我们通过添加一个进度条和更新工具栏的副标题来修饰一下它。

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

WebViewClient是响应呈现事件的接口;WebChromeClient是一个事件接口,用于响应应该改变浏览器周围chrome元素的事件。这包括JavaScript提醒、favicons,当然还有加载进度和当前页面标题的更新。

在onCreateView(…)中连接它。使用WebChromeClient来整理东西 进度更新和标题更新都有自己的回调方法, onProgressChanged(WebView, int)和onReceivedTitle(WebView, String)。你从onProgressChanged(WebView, int)接收到的进度是一个从0到100的整数。如果是100 页面已经完成加载,所以你隐藏ProgressBar通过设置它的可见性为View.GONE。

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

从源代码:

// 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对话框,favicons,标题和进度。看一下这个例子:向WebView添加alert()支持

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

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

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

你的WebView将(理论上)实现所有的功能(作为android原生浏览器)。