现在的位置: 首页 > 综合 > 正文

Android之WebViewClient与WebChromeClient的区别

2017年11月08日 ⁄ 综合 ⁄ 共 6593字 ⁄ 字号 评论关闭

<span style="font-family: Arial, Helvetica, sans-serif;"></span><p style="margin-top: 0px; margin-bottom: 8px; padding-top: 0px; padding-bottom: 0px; border-width: 0px; list-style: none; text-indent: 2em; color: rgb(51, 51, 51); font-family: 宋体; font-size: 14px; line-height: 28px;">ANDROID应用开发的时候可能会用到WEBVIEW这个组件,使用过程中可能会接触到WEBVIEWCLIENT与WEBCHROMECLIENT,那么这两个类到底有什么不同呢?
WebViewClient主要帮助WebView处理各种通知、请求事件的,比如:public boolean shouldOverrideUrlLoading(WebView view, String url) //进行对网页的重载
onLoadResource(WebView view, String url);//通知app webview即将加载 制定网址的资源
onPageStart(WebView view, String url, Bitmap favicon);//通知页面正在加载url,并且此方法只会在主Frame中调用一次,如果页面包含多个iframe 或 frameset ,只会在整个页面的主      Frame中加载,其他的iframe不会加载;同时也不会在页面中内嵌的 frame调用    onPageFinish(WebView view, String url);//通知页面结束加载,同样也只会在主frame被调用,一旦调用,渲染图片将不会再更新了。若需要接收新图片的通知,需要使用WebView.PictureListener#onNewPicture
public WebResourceResponse shouldInterceptRequest(WebView view, String url) 是否需要对url进行拦截?返回空,则不处理。可以进行重写,此方法运行在后台线程而不是UI线程,需要注意</p>
<span style="font-family: Arial, Helvetica, sans-serif;">public void onReceivedError(WebView view, int errorCode,</span>

            String description, String failingUrl)

报告访问错误,这种错误是无法补救的.(例如资源无法找到,404、505、500 etc)错误的类型如下 

// These ints must match up to the hidden values in EventHandler.
    /** Generic error */
    public static final int ERROR_UNKNOWN = -1;
    /** Server or proxy hostname lookup failed */
    public static final int ERROR_HOST_LOOKUP = -2;
    /** Unsupported authentication scheme (not basic or digest) */
    public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3;
    /** User authentication failed on server */
    public static final int ERROR_AUTHENTICATION = -4;
    /** User authentication failed on proxy */
    public static final int ERROR_PROXY_AUTHENTICATION = -5;
    /** Failed to connect to the server */
    public static final int ERROR_CONNECT = -6;
    /** Failed to read or write to the server */
    public static final int ERROR_IO = -7;
    /** Connection timed out */
    public static final int ERROR_TIMEOUT = -8;
    /** Too many redirects */
    public static final int ERROR_REDIRECT_LOOP = -9;
    /** Unsupported URI scheme */
    public static final int ERROR_UNSUPPORTED_SCHEME = -10;
    /** Failed to perform SSL handshake */
    public static final int ERROR_FAILED_SSL_HANDSHAKE = -11;
    /** Malformed URL */
    public static final int ERROR_BAD_URL = -12;
    /** Generic file error */
    public static final int ERROR_FILE = -13;
    /** File not found */
    public static final int ERROR_FILE_NOT_FOUND = -14;
    /** Too many requests during this load */
    public static final int ERROR_TOO_MANY_REQUESTS = -15;

public void onFormResubmission(WebView view, Message dontResend,
            Message resend) 

对于表单如果重新刷新,会触发这个函数,默认是 不重新发送请求,如果需要重新发送请求需要重写,实现.例如:

private class mWebViewClient extends WebViewClient{
@Override
public void onFormResubmission (WebView view, Message dontResend, Message resend){

L.v("### FORM ","## FORM RE SUBMIT");
resend.sendToTarget();
Toast.makeText(getApplicationContext(), "RESUBMIT DATA", Toast.LENGTH_LONG).show();
}
}

public void doUpdateVisitedHistory(WebView view, String url,
            boolean isReload)

通知更新宿主应用,更新已经访问过的连接地址的数据库

public void onReceivedHttpAuthRequest(WebView view,
            HttpAuthHandler handler, String host, String realm)

http需要授权请求,默认取消授权请求,必要时可以使用handler设置webview的请求回应

 public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) 

对按键的重在,return false webview 会自动拦截按键事件,return true 的话webview不会处理按键。

 public void onScaleChanged(WebView view, float oldScale, float newScale)

webview缩放改变的通知

可以进行对WevViewClient的重写进行扩充

//eg :

</pre><pre name="code" class="java">package ×××××;
import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.impl.client.DefaultHttpClient;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.webkit.WebView;
import android.webkit.WebViewClient;

/*
 * 默认的WebViewClient,
 * 有其他需求,可以拓展DefaultWebViewClient,重写onPageFinished方法
 * 不能使用WebChromeClient,打开http网页时候,会自动选择浏览器进行打开
 */
public class DefaultWebViewClient extends WebViewClient {
	private Context mContext;
	private String TAG = DefaultWebViewClient.class.getSimpleName();

	public DefaultWebViewClient() {
		super();
	}

	public DefaultWebViewClient(Context context) {
		this();
		this.mContext = context;
	}

	@Override
	public void onPageFinished(WebView view, String url) {
		super.onPageFinished(view, url);
		String windowOnloadJS = "javascript:window." + Constants.OBJECT_PREFIX
				+ "Onload(0)";
		view.loadUrl(windowOnloadJS);
	}

	@Override
	public boolean shouldOverrideUrlLoading(WebView view, String url) {
		if (url.startsWith("mailto:")) {
			String mail = url.replaceFirst("mailto:", "");
			Intent intent = new Intent(Intent.ACTION_SEND);
			intent.setType("message/rfc822");
			intent.putExtra(Intent.EXTRA_EMAIL, mail);
			try {
				mContext.startActivity(intent);
			} catch (ActivityNotFoundException exception) {
				ToastUtil.promptShortTime(mContext, ResourcesUtil
						.getStringResIndentifier("email_client_not_found"));
			}
		} else {
			if (url.startsWith("http://") || url.startsWith("www")) {
				if (getRespStatus(url) != 200) {
					onErrorWeb(view, url);
				} else
					view.loadUrl(url);
			} else {
				view.loadUrl(url);
			}
		}
		return true;
	}

	@Override
	public void onReceivedError(WebView view, int errorCode,
			String description, String failingUrl) {
		// TODO Auto-generated method stub
		// String data = FileUtils.getFromAssets("error_1.html", this.mContext);
		// String imgdata = "<img>";
		// view.loadData(data, "text/html", "utf-8");
		// view.loadUrl("javascript:document.body.innerHTML=\"" + data + "\"");
		// view.loadUrl("file:///android_asset/error.html");

		// view.loadUrl("javascript:document.getElementsByTagName('html').innerHTML=\""
		// + "啊是的发发是发" + "\"");
		super.onReceivedError(view, errorCode, description, failingUrl);

		// view.loadData(customHtml, "text/html", "UTF-8");
		onErrorWeb(view, failingUrl);
	}

	protected void onErrorWeb(WebView view, String failUrl) {
		String customHtml = FileUtils
				.getFromAssets("error.html", this.mContext);
		view.stopLoading();
		view.loadDataWithBaseURL(failUrl, customHtml, null, "UTF-8", failUrl);
	}

	int status = -1;

	private int getRespStatus(final String url) {

		try {
			ActivityUtil.runOnUIThread(mContext, new Runnable() {
				@Override
				public void run() {
					try {
						HttpHead head = new HttpHead(url);
						HttpClient client = new DefaultHttpClient();
						HttpResponse resp = client.execute(head);
						status = resp.getStatusLine().getStatusCode();
					} catch (IOException e) {
						// TODO: handle exception
					}

				}
			});
		} catch (Exception e) {
			LogUtil.e(TAG,
					"Current Window Executes JS occurs errors:" + e.toString());
		}
		return status;
	}
}


WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等比如

onCloseWindow(关闭WebView)
    onCreateWindow()
   onJsAlert (WebView上alert无效,需要定制WebChromeClient处理弹出)
   onJsPrompt
   onJsConfirm
   onProgressChanged
   onReceivedIcon
   onReceivedTitle
看上去他们有很多不同,实际使用的话,如果你的WebView只是用来处理一些html的页面内容,只用WebViewClient就行了,如果需要更丰富的处理效果,比如JS、进度条等,就要用到WebChromeClient。
更多的时候,你可以这样


WebView webView;
webView= (WebView) findViewById(R.id.webview);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(url);
这样你的WebView理论上就能有大部分需要实现的特色了
当然,有些更精彩的内容还是需要你自己添加的



摘自 程序之路

【上篇】
【下篇】

抱歉!评论已关闭.