android webview 使用以及一些常见的异常处理

标签: android webview 常见 | 发表时间:2014-08-17 20:12 | 作者:liuguofeng
出处:http://www.iteye.com

android中的提供webview控件,可以方便开发人员是自己的应用嵌入网页浏览功能,但实际开发中却会遇到 一些问题,这个稍后会介绍到,

效果图:

 

先来看个实例:

 

  1. public class MainActivity extends Activity {  
  2.     final String COMPANY_WEB="http://www.csdn.net";  
  3.     private WebView mWebView;  
  4.   
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.activity_main);  
  9.         mWebView = (WebView) findViewById(R.id.webview);  
  10.         setWebView();  
  11.           
  12.     }  
  13.   
  14.     private void setWebView(){  
  15.         WebSettings webSettings = mWebView.getSettings();  
  16.           webSettings.setJavaScriptEnabled(true);    
  17.           webSettings.setAllowFileAccess(true);    
  18.           webSettings.setBuiltInZoomControls(true);    
  19.           webSettings.setPluginsEnabled(true);  
  20.           
  21.         mWebView.setWebViewClient(new MonitorWebClient());  
  22.           
  23.         mWebView.loadUrl(COMPANY_WEB);  
  24.     }  
  25.       
  26.     private class MonitorWebClient extends WebViewClient{  
  27.   
  28.         @Override  
  29.         public void onPageStarted(WebView view, String url, Bitmap favicon) {  
  30.               
  31.             super.onPageStarted(view, url, favicon);  
  32.         }  
  33.           
  34.         @Override  
  35.         public void onPageFinished(WebView view, String url) {  
  36.               
  37.             super.onPageFinished(view, url);  
  38.         }  
  39.   
  40.         @Override  
  41.         public boolean shouldOverrideUrlLoading(WebView view, final String url) {  
  42.             String website=Uri.parse(url).getHost();  
  43.               
  44.             if (COMPANY_WEB.equals(website)) {  
  45.                     // This is my web site, so do not override; let my WebView load the page  
  46.                     return false;  
  47.               }else{  
  48.                  view.loadUrl(url);            
  49.                  return true;   
  50.              }  
  51.         //  return super.shouldOverrideUrlLoading(view, url);  
  52.         }  
  53.     }  
  54.       
  55.     @Override  
  56.     public boolean onKeyDown(int keyCode, KeyEvent event)  
  57.     {  
  58.         if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack())  
  59.         {  
  60.             mWebView.goBack();  
  61.             return true;  
  62.         }  
  63.         return super.onKeyDown(keyCode, event);  
  64.     }  
  65.       
  66. }  

 

 

相关权限:

 

  1. <uses-permission android:name="android.permission.INTERNET" />  
  2.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
  3.     <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。


好说的也差不多了,来看一下优化后的代码:

 

  1. public class MainActivity extends Activity {  
  2.   
  3.     final String COMPANY_WEB="http://www.deczh.com/";  
  4.     private WebView mWebView;  
  5.     private Context activity;  
  6. //  private ProgressDialog progressDialog;  
  7.     //history web site  
  8. //  private Stack<String> webHistory=new Stack<String>();  
  9.       
  10.     @Override  
  11.     protected void onCreate(Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.         setContentView(R.layout.activity_main);  
  14.         mWebView = (WebView) findViewById(R.id.webview);  
  15.         setWebView();  
  16.         activity=this;  
  17.         mHandler.sendEmptyMessageDelayed(0, 1000);  
  18.     }  
  19.       
  20.     private void setWebView(){  
  21.         WebSettings webSettings = mWebView.getSettings();  
  22.          //java script  
  23.           webSettings.setJavaScriptEnabled(true);    
  24.           webSettings.setJavaScriptCanOpenWindowsAutomatically(true);  
  25.           // access Assets and resources  
  26.           webSettings.setAllowFileAccess(true);    
  27.           //zoom page  
  28.           webSettings.setBuiltInZoomControls(true);    
  29.           webSettings.setPluginsEnabled(true);  
  30.           //set xml dom cache  
  31.           webSettings.setDomStorageEnabled(true);  
  32.           //提高渲染的优先级  
  33.           webSettings.setRenderPriority(RenderPriority.HIGH);    
  34.           //set cache  
  35.           String appCachePath = getDir("netCache", Context.MODE_PRIVATE).getAbsolutePath();  
  36.           webSettings.setAppCacheEnabled(true);  
  37.           webSettings.setAppCachePath(appCachePath);  
  38.           webSettings.setAppCacheMaxSize(1024*1024*5);  
  39.           webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);  
  40.           
  41.         mWebView.setWebViewClient(new MonitorWebClient());  
  42.         mWebView.setWebChromeClient(new AppCacheWebChromeClient());  
  43.     }  
  44.       
  45.     private class MonitorWebClient extends WebViewClient{  
  46.   
  47.         @Override  
  48.         public void onReceivedError(WebView view, int errorCode,  
  49.                 String description, String failingUrl) {  
  50.             //错误提示  
  51.             Toast toast = Toast.makeText(getBaseContext(), "Oh no! " + description,  
  52.                     Toast.LENGTH_LONG);  
  53.             toast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 0);  
  54.             toast.show();  
  55.             //错误<strong>处理</strong>  
  56.             try {  
  57.                 mWebView.stopLoading();  
  58.             } catch (Exception e) {  
  59.             }  
  60.             try {  
  61.                 mWebView.clearView();  
  62.             } catch (Exception e) {  
  63.             }  
  64.             if (mWebView.canGoBack()) {  
  65.                 mWebView.goBack();  
  66.             }  
  67.         //  super.onReceivedError(view, errorCode, description, failingUrl);  
  68.         }  
  69.         //当load有ssl层的https页面时,如果这个网站的安全证书在Android无法得到认证,WebView就会变成一个空白页,而并不会像PC浏览器中那样跳出一个风险提示框  
  70.         @Override  
  71.         public void onReceivedSslError(WebView view, SslErrorHandler handler,  
  72.                 SslError error) {  
  73.             //忽略证书的错误继续Load页面内容  
  74.              handler.proceed();  
  75.             //handler.cancel(); // Android默认的<strong>处理</strong>方式  
  76.              //handleMessage(Message msg); // 进行其他<strong>处理</strong>  
  77.         //  super.onReceivedSslError(view, handler, error);  
  78.         }  
  79.   
  80.         @Override  
  81.         public void onPageStarted(WebView view, String url, Bitmap favicon) {  
  82.              /*if (progressDialog == null) { 
  83.                  // If no progress dialog, make one and set message 
  84.                  progressDialog = new ProgressDialog(activity); 
  85.                  progressDialog.setMessage("Loading please wait..."); 
  86.                  progressDialog.show(); 
  87.                  // Hide the webview while loading 
  88.                  mWebView.setEnabled(false); 
  89.              }*/  
  90.               
  91.         //  super.onPageStarted(view, url, favicon);  
  92.         }  
  93.           
  94.         @Override  
  95.         public void onPageFinished(WebView view, String url) {  
  96.            /* if (progressDialog != null&&progressDialog.isShowing()) { 
  97.                 progressDialog.dismiss(); 
  98.                 progressDialog = null; 
  99.                 mWebView.setEnabled(true); 
  100.             }*/  
  101.               
  102.             /*if(!webHistory.contains(url)) 
  103.                 webHistory.push(url);*/  
  104.               
  105.         //  super.onPageFinished(view, url);  
  106.         }  
  107.   
  108.         @Override  
  109.         public boolean shouldOverrideUrlLoading(WebView view, final String url) {   Log.e(getClass().getSimpleName(), "website= "+url);  
  110.         //  String website=Uri.parse(url).getHost();  
  111.             String processUrl=url;  
  112.             if(!processUrl.startsWith("http://"))  
  113.                 processUrl="http://"+processUrl;  
  114.               
  115.             if (COMPANY_WEB.equals(url)) {  
  116.                // This is my web site, so do not override; let my WebView load the page  
  117.                  return false;  
  118.               }  
  119.             else{  
  120.                  view.loadUrl(processUrl);            
  121.                  return true;   
  122.              }  
  123.         //   return super.shouldOverrideUrlLoading(view, url);  
  124.         }  
  125.     }  
  126.       
  127.      private class AppCacheWebChromeClient extends WebChromeClient {  
  128.             @Override  
  129.             public void onReachedMaxAppCacheSize(long spaceNeeded, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {  
  130.             //    Log.e(APP_CACHE, "onReachedMaxAppCacheSize reached, increasing space: " + spaceNeeded);  
  131.                 quotaUpdater.updateQuota(spaceNeeded * 2);  
  132.             }  
  133.         }  
  134.        
  135.     private boolean pause=false;  
  136.     @Override  
  137.     public void onPause() {  
  138.         super.onPause();  
  139.         if (mWebView != null) {  
  140.             mWebView.pauseTimers();  
  141.             mWebView.onPause();  
  142.             this.pause=true;  
  143.         }  
  144.     }  
  145.   
  146.     @Override  
  147.     public void onResume() {  
  148.         super.onResume();  
  149.         if (mWebView != null&&pause) {  
  150.             mWebView.resumeTimers();  
  151.             mWebView.onResume();  
  152.             this.pause=false;  
  153.         }  
  154.     }  
  155.       
  156.     @Override  
  157.     public boolean onKeyDown(int keyCode, KeyEvent event)  
  158.     {  
  159.         if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()){  
  160.             mWebView.goBack();  
  161.             return true;  
  162.         }  
  163.          
  164.         return super.onKeyDown(keyCode, event);  
  165.     }  
  166.       
  167.       
  168. }  


相关权限:

 

 

  1. <uses-permission android:name="android.permission.INTERNET" />  
  2.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
  3.     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  
  4.   
  5.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  6.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  


经过代码优化后,访问速度明显提升,部分错误得到 处理,但是还是会有 异常 处理不了,如果谁有好的错误 处理方法,希望留言讨论,大家一起进步。

 

好了就先说到这里吧!



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [android webview 常见] 推荐:

Android WebView 常见的九个问题

- - 移动开发 - ITeye博客
关注微信号:javalearns   随时随地学Java. 目前Android WebView问题越来越多,接下来由爱内测(www.ineice.com)的技术工程师为我们介绍几种常见的Android WebView问题:. 1.为WebView自定义错误显示界面: /** * 显示自定义错误提示页面,用一个View覆盖在WebView */ protected void showErrorPage() { LinearLayout webParentView = (LinearLayout)mWebView.getParent();.

Android WebView 用法

- - 移动开发 - ITeye博客
Android和iOS系统都提供了标准的浏览器控件,在Android中是WebView,iOS中为UIWebView. 在iOS中你实例化一 个UIWebView即可调用loadRequest来加载一个网页,但是在Android中你不仅需要创建一个WebView,还需要做一些其他的事 情,建议初次使用WebView的读者按照以下步骤使用:.

android webview 使用以及一些常见的异常处理

- - 移动开发 - ITeye博客
android中的提供webview控件,可以方便开发人员是自己的应用嵌入网页浏览功能,但实际开发中却会遇到 一些问题,这个稍后会介绍到,. 回过头来在首页点击相关新闻链接后会发现出现空白页无法正常访问,后来研究发现这个和网站结构有关系,看来webview并不能完全实现浏览器功能. 接下来就是简单的 异常 处理了,主要就是重写WebViewClient类中的onReceivedError()方法和onReceivedSslError()方法来进行 处理了.

Android WebView常见问题及解决方案汇总

- - 移动开发 - ITeye博客
如有转载,请声明出处: 时之沙:  http://blog.csdn.net/t12x3456. Android WebView常见问题解决方案汇总:. 就目前而言,如何应对版本的频繁更新呢,又如何灵活多变地展示我们的界面呢,这又涉及到了web app与native app之间孰优孰劣的争论. 于是乎,一种混合型的app诞生了,灵活多变的部分,如淘宝商城首页的活动页面,一集凡客诚品中我们都可以见到web 页面与native页面的混合,既利用了web app的灵活易更新,也借助了native app本身的效率.

android WebView详解,常见漏洞详解和安全源码

- - CSDN博客推荐文章
  这篇博客主要来介绍 WebView 的相关使用方法,常见的几个漏洞,开发中可能遇到的坑和最后解决相应漏洞的源码,以及针对该源码的解析.   转载请注明出处: http://blog.csdn.net/self_study/article/details/54928371.   对技术感兴趣的同鞋加群 544645972 一起交流.

Android WebView的坑总结

- - CSDN博客推荐文章
       最近把做好的iPad HybridApp向Android迁移,碰到的坑太多了,让我这个折腾过Android接近4年的老鸟都头疼. 现在把前人遇到的都列出来,再慢慢解决自己的,目前已经解决了android键盘覆盖问题,下面最棘手的问题就是屏幕高度的适配问题了. 1、 Andrid4.1事件穿透BUG 原因不明.

Android中WebView页面交互

- - SegmentFault 最新的文章
在android内打开一个网页的时候,有时我们会要求与网页有一些交互. 而这些交互是在基于javaScript的基础上. 那么我们来学习一下android如何与网页进行JS交互. protected View refresh;// 刷新按钮. protected String url = "";// 网址url.

Android: 在WebView中获取网页源码

- - ITeye博客
 使能javascript:. 编写自己的WebViewClient,并在onPageFinished中提取网页源码. 运行,可以看到在showSource(String html)中打印了网页源码. 已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

Android WebView中的JavaScript代码使用

- - 博客园_首页
  上一篇博文: Android WebView使用基础已经说了一些Android中WebView的基本使用.   本篇文章主要介绍WebView中的JavaScript代码的执行相关,已经JS代码与Android代码的互相调用.   (因为本人对Web开发并不是很熟悉,所以如果有哪些地方说得不对,还请指正.

Android WebView与Native通信总结

- - 掘金 架构
当前移动端App的开发很多都需要内嵌WebView来方便业务的快速开展,特别是电商App中,业务变化快,活动多. 仅仅依靠native的开发方式难以满足快速的业务发展,于是混合开发模式便出现. 当前比较知名的有 Cordova,. Ionic, 国内的有 Appcan,. APICloud开发平台,这几种都是依赖于WebView的实现.