Android WebView使用详解

最近项目中用到WebView, 就根据自己项目的需求重写了个WebView。 下面简单介绍一下使用情况,以作记忆~~

前面本人写过一个WebView加载进度显示的博客,有需要的可以去看看:WebView加载进度Progress的显示


一、WebView基本属性设置

下面只是根据个人项目需求设置的部分属性,还有其他属性,读者可以查看相关文档,选择自己需要的属性设置,不多说。

	private void init(Context context) {
		//添加进度 条
		mProgressbar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
		mProgressbar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 5, 0, 0));
		addView(mProgressbar);
		
		WebSettings webSettings = this.getSettings();
		webSettings.setJavaScriptEnabled(true);
		webSettings.setSupportZoom(true);
		//webSettings.setUseWideViewPort(true);
		this.requestFocus();
		this.setWebViewClient(mWebViewClient);
		this.setWebChromeClient(mWebChromeClient);
		this.setDownloadListener(mDownloadListener);
		this.loadUrl(mUrl);
		this.onResume();
	}



二、WebViewClient使用

       WebViewClient主要提供网页加载各个阶段的通知回调,比如网页开始加载的onPageStarted,网页结束加载onPageFinished等,所以有关网页加载的设计在这里实现。

	private WebViewClient mWebViewClient = new WebViewClient() {

		@Override
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			// TODO Auto-generated method stub
			Log.i(TAG, "shouldOverrideUrlLoading : ");
			return super.shouldOverrideUrlLoading(view, url);
		}

		@Override
		public void onPageStarted(WebView view, String url, Bitmap favicon) {
			// TODO Auto-generated method stub
			Log.i(TAG, "onPageStarted : "+url);
			if (StringUtil.isStartWith(url, "market://")) {
				Log.i(TAG, "onPageStarted : start with market");
				if (PackageUtil.isApkAvailable(mActivity, "com.android.vending")) {
					//隐藏webview,显示google paly store
					Log.i(TAG, "onPageStarted : google play");
					mActivity.moveTaskToBack(true);
					Uri uri = Uri.parse(url);
					Intent intent = new Intent(Intent.ACTION_VIEW, uri);
					mActivity.startActivity(intent);
					
					//统计GP打开的数量
					StatsHelper.statAdGoGP(Constants.GALabel.ADS_GoGP_BYGP, mId);
					
					mActivity.finish();
				} else {
					Log.i(TAG, "onPageStarted : no google play");
					url = StringUtil.replaceSubString(url, "market://", "https://play.google.com/store/apps/");
					Log.i(TAG, "onPageStarted replace : "+url);
					loadUrl(url);
					
					//统计web打开的数量
					StatsHelper.statAdGoWeb(Constants.GALabel.ADS_GoGP_BYWEB, mId);
				}
			}
			super.onPageStarted(view, url, favicon);
		}

		@Override
		public void onPageFinished(WebView view, String url) {
			// TODO Auto-generated method stub
			Log.i(TAG, "onPageFinished : ");
			super.onPageFinished(view, url);
		}

		@Override
		public void onReceivedError(WebView view, int errorCode,
				String description, String failingUrl) {
			// TODO Auto-generated method stub
			Log.i(TAG, "onReceivedError : ");
			super.onReceivedError(view, errorCode, description, failingUrl);
		}

		@Override
		public void doUpdateVisitedHistory(WebView view, String url,
				boolean isReload) {
			// TODO Auto-generated method stub
			Log.i(TAG, "doUpdateVisitedHistory : ");
			super.doUpdateVisitedHistory(view, url, isReload);
		}
	};



三、WebChromeClient的使用

       WebChromeClient主要提供网页加载过程中用户需要的数据内容,比如返回网页的title/favicon,网页加载进度progress等。

	private WebChromeClient mWebChromeClient = new WebChromeClient() {

		@Override
		public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress == 100) {
            	mProgressbar.setVisibility(GONE);
            } else {
                if (mProgressbar.getVisibility() == GONE)
                	mProgressbar.setVisibility(VISIBLE);
                mProgressbar.setProgress(newProgress);
            }
            super.onProgressChanged(view, newProgress);
		}

		@Override
		public void onReceivedTitle(WebView view, String title) {
			// TODO Auto-generated method stub
			super.onReceivedTitle(view, title);
		}

		@Override
		public void onReceivedTouchIconUrl(WebView view, String url,
				boolean precomposed) {
			// TODO Auto-generated method stub
			super.onReceivedTouchIconUrl(view, url, precomposed);
		}

		@Override
		public boolean onCreateWindow(WebView view, boolean isDialog,
				boolean isUserGesture, Message resultMsg) {
			// TODO Auto-generated method stub
			return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);
		}
		
	};



四、下载监听DownloadListener使用

       当用户点击网页跳转到下载时,用户又应该如何监听该下载呢? 答案很简单,就是用DownloadListener进行监听。

	private DownloadListener mDownloadListener = new DownloadListener() {

		@Override
		public void onDownloadStart(String url, String userAgent,
				String contentDisposition, String mimetype, long contentLength) {
			// TODO Auto-generated method stub
			Log.i(TAG, "onDownloadStart url = "+url);
//			DownloaderTask task=new DownloaderTask();
//			task.execute(url);
			try {  //调用系统下载管理器
				DownloadBySystem download = new DownloadBySystem(mActivity);
				download.download(mId, url);
				//统计下载
				StatsHelper.statAdDownload(Constants.GALabel.ADS_LOAD_SYSTEM, mId);
			} catch (Exception e) {  //如果手机下载管理器关闭或不能使用,则使用webview下载
				// TODO: handle exception
//				DownloaderTask task = new DownloaderTask();
//				task.execute(url);
				DownloadByMyself download = new DownloadByMyself(mActivity);
				download.download(mId, url);
				//统计下载
				StatsHelper.statAdDownload(Constants.GALabel.ADS_LOAD_WEBVIEW, mId);
			}

		}
		
	};



五、如何回退上一页

       如果在webview中进行了多次跳转,按back键只会回退到上一个页面,而不是直接退出webview,又应该如何实现?这个也不难,只要监听到back键的事件,然后让webview来消耗该事件,实现webview的回退功能,就OK~~

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if (keyCode == KeyEvent.KEYCODE_BACK && this.canGoBack()) {
			this.goBack();
			return true;
		}
		return false;
	} 



六、监听webview的滚动

       滚动在webview设置在有进度条时很有必要,比如,webview在头部设置了进度条,如果你不再做一些处理,那么在webview向上滚动时,进度条就会向上滚动,当然也就隐藏掉了。所以在onScrollChanged中做一些处理十分必要

	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		// TODO Auto-generated method stub
        LayoutParams lp = (LayoutParams) mProgressbar.getLayoutParams();
        lp.x = l;
        lp.y = t;
        mProgressbar.setLayoutParams(lp);
        super.onScrollChanged(l, t, oldl, oldt);
	}



七、 代码

         下面是我重写的WebView的全部代码,仅供参考:

package com.mobisummer.ads.banner;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.DownloadListener;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

import com.mobisummer.ads.banner.util.Constants;
import com.mobisummer.ads.banner.util.DownloadByMyself;
import com.mobisummer.ads.banner.util.DownloadBySystem;
import com.mobisummer.ads.banner.util.FileUtil;
import com.mobisummer.ads.banner.util.PackageUtil;
import com.mobisummer.ads.banner.util.StatsHelper;
import com.mobisummer.ads.banner.util.StringUtil;

public class AdsWebView extends WebView {
	private static final String TAG = "wxx";
	private Activity mActivity;
	private String mUrl;
	private int mId;
	private ProgressBar mProgressbar;
	
	public AdsWebView(Context context, int id, String url) {
		super(context);
		this.mActivity = (Activity) context;
		this.mUrl = url;
		this.mId = id;
		init(context);
	}

	
	@SuppressLint({ "SetJavaScriptEnabled", "NewApi" })
	private void init(Context context) {
		//添加进度 条
		mProgressbar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
		mProgressbar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 5, 0, 0));
		addView(mProgressbar);
		
		WebSettings webSettings = this.getSettings();
		webSettings.setJavaScriptEnabled(true);
		webSettings.setSupportZoom(true);
		//webSettings.setUseWideViewPort(true);
		this.requestFocus();
		this.setWebViewClient(mWebViewClient);
		this.setWebChromeClient(mWebChromeClient);
		this.setDownloadListener(mDownloadListener);
		this.loadUrl(mUrl);
		this.onResume();
	}
	
	private WebViewClient mWebViewClient = new WebViewClient() {

		@Override
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			// TODO Auto-generated method stub
			Log.i(TAG, "shouldOverrideUrlLoading : ");
			return super.shouldOverrideUrlLoading(view, url);
		}

		@Override
		public void onPageStarted(WebView view, String url, Bitmap favicon) {
			// TODO Auto-generated method stub
			Log.i(TAG, "onPageStarted : "+url);
			if (StringUtil.isStartWith(url, "market://")) {
				Log.i(TAG, "onPageStarted : start with market");
				if (PackageUtil.isApkAvailable(mActivity, "com.android.vending")) {
					//隐藏webview,显示google paly store
					Log.i(TAG, "onPageStarted : google play");
					mActivity.moveTaskToBack(true);
					Uri uri = Uri.parse(url);
					Intent intent = new Intent(Intent.ACTION_VIEW, uri);
					mActivity.startActivity(intent);
					
					//统计GP打开的数量
					StatsHelper.statAdGoGP(Constants.GALabel.ADS_GoGP_BYGP, mId);
					
					mActivity.finish();
				} else {
					Log.i(TAG, "onPageStarted : no google play");
					url = StringUtil.replaceSubString(url, "market://", "https://play.google.com/store/apps/");
					Log.i(TAG, "onPageStarted replace : "+url);
					loadUrl(url);
					
					//统计web打开的数量
					StatsHelper.statAdGoWeb(Constants.GALabel.ADS_GoGP_BYWEB, mId);
				}
			}
			super.onPageStarted(view, url, favicon);
		}

		@Override
		public void onPageFinished(WebView view, String url) {
			// TODO Auto-generated method stub
			Log.i(TAG, "onPageFinished : ");
			super.onPageFinished(view, url);
		}

		@Override
		public void onReceivedError(WebView view, int errorCode,
				String description, String failingUrl) {
			// TODO Auto-generated method stub
			Log.i(TAG, "onReceivedError : ");
			super.onReceivedError(view, errorCode, description, failingUrl);
		}

		@Override
		public void doUpdateVisitedHistory(WebView view, String url,
				boolean isReload) {
			// TODO Auto-generated method stub
			Log.i(TAG, "doUpdateVisitedHistory : ");
			super.doUpdateVisitedHistory(view, url, isReload);
		}
	};
	
	private WebChromeClient mWebChromeClient = new WebChromeClient() {

		@Override
		public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress == 100) {
            	mProgressbar.setVisibility(GONE);
            } else {
                if (mProgressbar.getVisibility() == GONE)
                	mProgressbar.setVisibility(VISIBLE);
                mProgressbar.setProgress(newProgress);
            }
            super.onProgressChanged(view, newProgress);
		}

		@Override
		public void onReceivedTitle(WebView view, String title) {
			// TODO Auto-generated method stub
			super.onReceivedTitle(view, title);
		}

		@Override
		public void onReceivedTouchIconUrl(WebView view, String url,
				boolean precomposed) {
			// TODO Auto-generated method stub
			super.onReceivedTouchIconUrl(view, url, precomposed);
		}

		@Override
		public boolean onCreateWindow(WebView view, boolean isDialog,
				boolean isUserGesture, Message resultMsg) {
			// TODO Auto-generated method stub
			return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);
		}
		
	};

	private DownloadListener mDownloadListener = new DownloadListener() {

		@Override
		public void onDownloadStart(String url, String userAgent,
				String contentDisposition, String mimetype, long contentLength) {
			// TODO Auto-generated method stub
			Log.i(TAG, "onDownloadStart url = "+url);
//			DownloaderTask task=new DownloaderTask();
//			task.execute(url);
			try {  //调用系统下载管理器
				DownloadBySystem download = new DownloadBySystem(mActivity);
				download.download(mId, url);
				//统计下载
				StatsHelper.statAdDownload(Constants.GALabel.ADS_LOAD_SYSTEM, mId);
			} catch (Exception e) {  //如果手机下载管理器关闭或不能使用,则使用webview下载
				// TODO: handle exception
//				DownloaderTask task = new DownloaderTask();
//				task.execute(url);
				DownloadByMyself download = new DownloadByMyself(mActivity);
				download.download(mId, url);
				//统计下载
				StatsHelper.statAdDownload(Constants.GALabel.ADS_LOAD_WEBVIEW, mId);
			}

		}
		
	};
	
	private class DownloaderTask extends AsyncTask<String, Integer, String> { 

	    public DownloaderTask() { 
	    }

		@Override
		protected String doInBackground(String... params) {
			// TODO Auto-generated method stub
			Log.i(TAG, "doInBackground");
			String path = params[0];
			String fileName = path.substring(path.lastIndexOf("/")+1);
			fileName = StringUtil.getFrontSubString(fileName, ".apk");
			fileName = URLDecoder.decode(fileName);
			Log.i(TAG, "fileName="+fileName);
			
			String directory = Environment.getExternalStorageDirectory().toString() + "/download/";
			File apkFile = new File(directory,fileName);
			if(apkFile.exists()){
				Log.i(TAG, "The file has already exists.");
				if (PackageUtil.getUninallApkInfo(mActivity, apkFile.getAbsolutePath())) {
					return fileName;
				} else {
					Log.d(TAG, "apk is not all...");
					FileUtil.deleteFile(apkFile);
				}
			}
			try {
				URL url = new URL(path);
				HttpURLConnection connection = (HttpURLConnection) url.openConnection();
				connection.connect();

				if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
					InputStream is = connection.getInputStream();
					FileOutputStream fos = new FileOutputStream(apkFile);
					int length = connection.getContentLength();
					byte buf[] = new byte[1024];
					int count = 0;
					int read = 0;
					int progress = 0;
					while (true) {
						read = is.read(buf);
						if (read <= 0) {
							break;
						}
						count += read;
						progress = (int) (((float)count / length) * 100);
						Log.i(TAG, "download progress = "+progress);
						publishProgress(progress);
						fos.write(buf, 0, read);
					}
					fos.close();
					is.close();
					Log.i(TAG, "download success....");
				}
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			return fileName;
		}

		@Override
		protected void onCancelled() {
			// TODO Auto-generated method stub
			super.onCancelled();
		}

		@Override
		protected void onPostExecute(String result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			Log.i(TAG, "onPostExecute");
			
			String directory = Environment.getExternalStorageDirectory().toString() + "/download/";
			File file = new File(directory,result);
			//判断是否下载完整
			if (PackageUtil.getUninallApkInfo(mActivity, file.getAbsolutePath())) {
				Log.d(TAG, "download is all....");
				//统计下载成功
				StatsHelper.statAdLoadSuccess(Constants.GALabel.ADS_LOAD_WEBVIEW, mId);
				
				Uri uri = Uri.fromFile(file);
				String mime = FileUtil.getMimeType(file.getName());
				
			    Intent intent = new Intent("android.intent.action.VIEW");
			    intent.addCategory("android.intent.category.DEFAULT");
			    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			    intent.setDataAndType(uri, mime);			
				mActivity.startActivity(intent);
			} else {
				Log.d(TAG, "download not all....");
			}
		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			// TODO Auto-generated method stub
			super.onProgressUpdate(values);
//			mProgressbar.setProgress(values[0]);
		} 
	}

	//保证向下流动webView时,Progress正常显示,而非隐藏
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		// TODO Auto-generated method stub
        LayoutParams lp = (LayoutParams) mProgressbar.getLayoutParams();
        lp.x = l;
        lp.y = t;
        mProgressbar.setLayoutParams(lp);
        super.onScrollChanged(l, t, oldl, oldt);
	}

	//设置WebView能够回退上一页,而非直接退出
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if (keyCode == KeyEvent.KEYCODE_BACK && this.canGoBack()) {
			this.goBack();
			return true;
		}
		return false;
	} 
	
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值