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

项目笔记—WebView详解

2018年05月16日 ⁄ 综合 ⁄ 共 6134字 ⁄ 字号 评论关闭
package com.example.webclient;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.webkit.DownloadListener;
import android.webkit.HttpAuthHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.RelativeLayout;
import android.widget.Toast;
/**
 * webview知识
 * http://blog.csdn.net/chenshijun0101/article/details/7045394
 * http://blog.csdn.net/kingsollyu/article/details/6656865(与JS进行交互)
 * @author chenxiaojian
 *
 */
public class MainActivity extends Activity {
	
	private WebView mWebView ;
	
	private Handler mHandler = new Handler();
	
	private static final String TAG = MainActivity.class.getName();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		initView();
	}
	@SuppressLint("JavascriptInterface")
	private void initView(){
		mWebView = new WebView(this);
		mWebView.setLayoutParams(new 
				RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
						ViewGroup.LayoutParams.MATCH_PARENT));
		setContentView(mWebView);
		
		mWebView.requestFocus();//获取焦点
		
		WebSettings webSettings = mWebView.getSettings();
		mWebView.setVerticalScrollBarEnabled(false);
		mWebView.setHorizontalScrollBarEnabled(false);
		//如果访问的页面中有Javascript,则webview必须设置支持Javascript。
		webSettings.setJavaScriptEnabled(true);
		//使用localStorage则必须打开 这个主要是用在html5中的本地存储。
		webSettings.setDomStorageEnabled(true);
		webSettings.setSaveFormData(false);
		//Webview与js的双向交互才是android的webview强大所在(因为安全问题在API17之后以取消) ,可以暂不关心
		mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "chen");
		
		
//		如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。
//		给WebView添加一个事件监听对象(WebViewClient)并重写其中的一些方法:
//		 shouldOverrideUrlLoading:对网页中超链接按钮的响应。当按下某个连接时WebViewClient会调用这个方法,
//		 并传递参数:按下的url。比如当webview内嵌网页的某个数字被点击时,它会自动认为这是一个电话请求,
//		 会传递url:tel:123,如果你不希望如此可通过重写shouldOverrideUrlLoading函数解决:
		//也就是说如果我们没有重写shouldOverrideUrlLoading会弹出一个系统浏览器,多么扯淡。
//		@Override
//		public boolean shouldOverrideUrlLoading(WebView view, String url) {
//			mWebView.loadUrl(url);
//			return true;
//		}
		
		
		mWebView.setWebViewClient(new MyWebClient());
		
		mWebView.setWebChromeClient(new MyWebChromeClient());
		
		mWebView.setDownloadListener(new WebViewDownloadListener());
		
//		设置WevView要显示的网页:
//      互联网用:webView.loadUrl("http://www.google.com"); 
//      本地文件用:webView.loadUrl("file:///android_asset/XX.html");  本地文件存放在:assets文件中
		mWebView.loadUrl("http://m.appchina.com");//internet权限没有加问题导致404
		
		
//		如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键,
//		整个浏览器会调用finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消费掉该Back事件。
//	    覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。
		
		
		
		mWebView.setOnKeyListener(new OnKeyListener() {
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if (keyCode == KeyEvent.KEYCODE_BACK && mWebView != null && mWebView.canGoBack()) {
					mWebView.goBack();
					return true;//return true表示这个事件已经被消费,不会再向上传播
				}
				return false;
			}
		});
		
		
	}
	/**
	 * 		WebClient和WebChromeClient的区别?
	 * 		 onLoadResource 
			 onPageStart 
			 onPageFinish 
			 onReceiveError 
			 onReceivedHttpAuthRequest 
			
			WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等 
			
			 onCloseWindow(关闭WebView) 
			 onCreateWindow() 
			 onJsAlert (WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出) 
			 onJsPrompt 
			 onJsConfirm 
			 onProgressChanged 
			 onReceivedIcon 
			 onReceivedTitle
	 * @author chenxiaojian
	 *
	 */
	final class MyWebClient extends WebViewClient{
		public MyWebClient() {
		}

		@Override
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			//这个方法是必须要重写的,如果不重写就是会调用系统浏览器自己处理了
			Log.v(TAG, "shouldOverrideUrlLoading "+url);
			view.loadUrl(url);
			return true;
		}
		/**
		 * 这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。
		 */
		@Override
		public void onPageStarted(WebView view, String url, Bitmap favicon) {
			Log.i(TAG, "onPageStarted "+url);
			//这个主要是先不让图片加载,似乎可以达到快速的目的。
			//但是在有的网页里面不可以详见:http://hi.baidu.com/goldchocobo/item/9f7b0639f3cd2efe96f88dfb
			view.getSettings().setBlockNetworkImage(true);
			super.onPageStarted(view, url, favicon);
		}
		/**
		 * 同样道理,我们知道一个页面载入完成,于是我们可以关闭loading条,切换程序动作。
		 */
		@Override
		public void onPageFinished(WebView view, String url) {
			Log.i(TAG, "onPageFinished "+url);
			view.getSettings().setBlockNetworkImage(false);
			super.onPageFinished(view, url);
		}

		@Override
		public void onLoadResource(WebView view, String url) {
			Log.i(TAG, "onLoadResource "+url);
			super.onLoadResource(view, url);
		}

		@Override
		public void onReceivedError(WebView view, int errorCode,
				String description, String failingUrl) {
			super.onReceivedError(view, errorCode, description, failingUrl);
			Log.e(TAG, "onReceivedError errorCode:"+errorCode+" description"+description+" failingUrl"+failingUrl);
//			finish();
		}
		/**
		 * 接收到Http请求的事件
		 */
		@Override
		public void onReceivedHttpAuthRequest(WebView view,
				HttpAuthHandler handler, String host, String realm) {
			super.onReceivedHttpAuthRequest(view, handler, host, realm);
		}
		
	}
	
	final class DemoJavaScriptInterface{
		public DemoJavaScriptInterface() {
		}
		/**
		 * 里面的方面必须到UI线程中去调用,所以要post一下。
		 * 这个在html里面的js里面的方面名是window.chen.clickOnAndroid()
		 */
		public void clickOnAndroid(){
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					// 此处调用 HTML 中的javaScript 函数
					mWebView.loadUrl("javascript:wave()");
				}
			});
		}
	}
	
	final class MyWebChromeClient extends WebChromeClient{
		public MyWebChromeClient() {
		}

		@Override
		public void onProgressChanged(WebView view,final int newProgress) {
			super.onProgressChanged(view, newProgress);
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					Toast.makeText(MainActivity.this, "加载进度 "+newProgress,Toast.LENGTH_SHORT).show();
				}
			});
		}

		@Override
		public void onReceivedTitle(WebView view, String title) {
			super.onReceivedTitle(view, title);
			Log.e(TAG, "标题Title "+title);
		}

		@Override
		public void onReceivedIcon(WebView view, Bitmap icon) {
			super.onReceivedIcon(view, icon);
		}
	}
	
	
	final class WebViewDownloadListener implements DownloadListener{

		@Override
		public void onDownloadStart(String url, String userAgent,
				String contentDisposition, String mimetype, long contentLength) {
			//这个只是暂时调用系统的,可以做一个自己的下载器。
			Uri uri = Uri.parse(url);
			Intent  intent = new Intent(Intent.ACTION_VIEW,uri);
			startActivity(intent);
		}
		
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	


}


http://download.csdn.net/detail/dacainiao007/7000097 回调
http://download.csdn.net/detail/dacainiao007/7035373 (本文源码)

抱歉!评论已关闭.