public class MainActivity extends Activity {
final String COMPANY_WEB="http://www.csdn.net";
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webview);
setWebView();
}
private void setWebView(){
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setPluginsEnabled(true);
mWebView.setWebViewClient(new MonitorWebClient());
mWebView.loadUrl(COMPANY_WEB);
}
private class MonitorWebClient extends WebViewClient{
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, final String url) {
String website=Uri.parse(url).getHost();
if (COMPANY_WEB.equals(website)) {
// This is my web site, so do not override; let my WebView load the page
return false;
}else{
view.loadUrl(url);
return true;
}
// return super.shouldOverrideUrlLoading(view, url);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack())
{
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
相关权限:
[java] view plaincopy
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
ok,测试了一下相关链接也可以出现正常访问,以上是以csdn网站为例,如果将网站换成http://www.qq.com开始也没有问题,点击导航栏也可以正常访问,再点击图片连接就会出现 eventhub.removemessages(int what = 107) is not supported before the webviewcore is set up异常信息,有人说是没有以http://开头,这个也试了一下,没有解决问题,期待有人能解决。回过头来在首页点击相关新闻链接后会发现出现空白页无法正常访问,后来研究发现这个和网站结构有关系,看来webview并不能完全实现浏览器功能。
接下来就是简单的异常处理了,主要就是重写WebViewClient类中的onReceivedError()方法和onReceivedSslError()方法来进行处理了。
说完异常简单处理后再来说说提高网站的访问速度,尤其是带有大量的flash,swf动画和各种css样式功能,这个时候我们就应该使用缓存了,适当的设置缓存大小以及合适的模式来进行优化了,webview有两种模式可设置如下:
1,LOAD_DEFAULT,根据cache-control决定是否从网络上取数据。
2,LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
如:m.taobao.com的cache-control为no-cache,在模式LOAD_DEFAULT下,无论如何都会从网络上取数据,如果没有网络,就会出现错误页面;在LOAD_CACHE_ELSE_NETWORK模式下,无论是否有网络,只要打开过一次,都使用缓存。
m.sina.com.cn的cache-control为max-age=60,在两种模式下都使用本地缓存数据。
总结:根据以上两种模式,建议缓存策略为,判断是否有网络,有的话,使用LOAD_DEFAULT,无网络时,使用LOAD_CACHE_ELSE_NETWORK。
好说的也差不多了,来看一下优化后的代码:
[java] view plaincopy
public class MainActivity extends Activity {
final String COMPANY_WEB="http://www.deczh.com/";
private WebView mWebView;
private Context activity;
// private ProgressDialog progressDialog;
//history web site
// private Stack<String> webHistory=new Stack<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webview);
setWebView();
activity=this;
mHandler.sendEmptyMessageDelayed(0, 1000);
}
private void setWebView(){
WebSettings webSettings = mWebView.getSettings();
//java script
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
// access Assets and resources
webSettings.setAllowFileAccess(true);
//zoom page
webSettings.setBuiltInZoomControls(false);
webSettings.setPluginsEnabled(true);
webSettings.setPluginState(WebSettings.PluginState.ON);
//提高渲染的优先级
webSettings.setRenderPriority(RenderPriority.HIGH);
webSettings.setEnableSmoothTransition(true);
//Cache开启和设置
// 一个页面的 图片\js\css 载入过之后
//在服务器设置的文件有效期内,每次请求,会去服务器检查文件最后修改时间,如果一致,不会重新下载,而是使用缓存
String appCachePath = mContext.getDir("netCache", Context.MODE_PRIVATE).getAbsolutePath();
webSettings.setAppCacheEnabled(true);
webSettings.setAppCachePath(appCachePath);
webSettings.setAppCacheMaxSize(1024*1024*5);
//会影响时时刷新结果
// webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//LocalStorage相关设置
// 像首页的DOM,第一次载入,需要从服务器ajax请求接口json配置数据,然后用js从模板中渲染拼接成DOM,显示在页面中
//由于Android webview的JS处理很慢,这里把第一次渲染后的DOM存入LocalStorage中,以后打开页面不用请求API和JS渲染,优先加载页面,和Cache配置,速度会快很多
//但是Android webview的LocalStorage有个问题,关闭APP或者重启后,就清楚了,所以需要下面browser.getSettings().setDatabase相关的操作,把LocalStoarge存到DB中
webSettings.setDatabaseEnabled(true);
webSettings.setDomStorageEnabled(true);
String databasePath = mContext.getDir("databases", Context.MODE_PRIVATE).getPath();
webSettings.setDatabasePath(databasePath);
mWebView.setWebViewClient(new MonitorWebClient());
mWebView.setWebChromeClient(new AppCacheWebChromeClient());
}
private class MonitorWebClient extends WebViewClient{
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
//错误提示
Toast toast = Toast.makeText(getBaseContext(), "Oh no! " + description,
Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 0);
toast.show();
//错误处理
try {
mWebView.stopLoading();
} catch (Exception e) {
}
try {
mWebView.clearView();
} catch (Exception e) {
}
if (mWebView.canGoBack()) {
mWebView.goBack();
}
// super.onReceivedError(view, errorCode, description, failingUrl);
}
//当load有ssl层的https页面时,如果这个网站的安全证书在Android无法得到认证,WebView就会变成一个空白页,而并不会像PC浏览器中那样跳出一个风险提示框
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler,
SslError error) {
//忽略证书的错误继续Load页面内容
handler.proceed();
//handler.cancel(); // Android默认的处理方式
//handleMessage(Message msg); // 进行其他处理
// super.onReceivedSslError(view, handler, error);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
/*if (progressDialog == null) {
// If no progress dialog, make one and set message
progressDialog = new ProgressDialog(activity);
progressDialog.setMessage("Loading please wait...");
progressDialog.show();
// Hide the webview while loading
mWebView.setEnabled(false);
}*/
// super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
/* if (progressDialog != null&&progressDialog.isShowing()) {
progressDialog.dismiss();
progressDialog = null;
mWebView.setEnabled(true);
}*/
/*if(!webHistory.contains(url))
webHistory.push(url);*/
// super.onPageFinished(view, url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, final String url) { Log.e(getClass().getSimpleName(), "website= "+url);
// String website=Uri.parse(url).getHost();
String processUrl=url;
if(!processUrl.startsWith("http://"))
processUrl="http://"+processUrl;
if (COMPANY_WEB.equals(url)) {
// This is my web site, so do not override; let my WebView load the page
return false;
}
else{
view.loadUrl(processUrl);
return true;
}
// return super.shouldOverrideUrlLoading(view, url);
}
}
private class AppCacheWebChromeClient extends WebChromeClient {
@Override
public void onReachedMaxAppCacheSize(long spaceNeeded, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
// Log.e(APP_CACHE, "onReachedMaxAppCacheSize reached, increasing space: " + spaceNeeded);
quotaUpdater.updateQuota(spaceNeeded * 2);
}
}
private boolean pause=false;
@Override
public void onPause() {
super.onPause();
if (mWebView != null) {
mWebView.pauseTimers();
mWebView.onPause();
this.pause=true;
}
}
@Override
public void onResume() {
super.onResume();
if (mWebView != null&&pause) {
mWebView.resumeTimers();
mWebView.onResume();
this.pause=false;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()){
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章