您的位置:首页 > 移动开发

Android WebView使用详解

2016-03-15 18:24 696 查看
最近项目中用到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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: