保存到桌面加入收藏设为首页
IOS开发
当前位置:首页 > IOS开发

WebView的使用及实战-安度博客

时间:2019-02-08 15:56:25   作者:   来源:   阅读:98   评论:0
内容摘要:这篇博客主要讲解一下问题- webView 的 基本使用- webView怎样配置缓存- webView请求错误时候的处理- webView COOKIE的同步与清除- webView 下载文件的两种方法- webView的 一些扩展使用思路图如下大概的效果图如下webView的......
  • 这篇博客主要讲解一下问题
    - webView 的 基本使用
    - webView怎样配置缓存
    - webView请求错误时候的处理
    - webView COOKIE的同步与清除
    - webView 下载文件的两种方法
    - webView的 一些扩展使用

    思路图如下

    大概的效果图如下

    webView的基本使用

    大概可以分为以下步骤
    - 配置权限
    - 创建webView
    - 配置webView(是否支持js,是否由系统浏览器打开)
    - 加载数据

    第一步,别忘了 在nk" target="_blank">AndroidMainfest中 添加权限

    <uses-permission android:name=&#39;android.permission.INTERNET&#39;/>

    第二步,创建webView

    在xml文件中

    <?xml version=&#39;1.0&#39; encoding=&#39;utf-8&#39;?><layout xmlns:android=&#39;http://schemas.android.com/apk/res/android&#39;> <RelativeLayout android:layout_width=&#39;match_parent&#39; android:layout_height=&#39;match_parent&#39; > <RelativeLayout android:id=&#39;@+id/rl_head&#39; android:layout_width=&#39;match_parent&#39; android:layout_height=&#39;?android:actionBarSize&#39; android:background=&#39;@color/colorAccent&#39;> <ImageView android:id=&#39;@+id/iv_back&#39; android:layout_width=&#39;wrap_content&#39; android:layout_height=&#39;wrap_content&#39; android:layout_centerVertical=&#39;true&#39; android:padding=&#39;10dp&#39; android:src=&#39;@drawable/sel_back&#39;/> <TextView android:id=&#39;@+id/tv_title&#39; android:layout_width=&#39;wrap_content&#39; android:layout_height=&#39;wrap_content&#39; android:layout_centerInParent=&#39;true&#39; android:ellipsize=&#39;end&#39; android:maxLength=&#39;200&#39; android:maxLines=&#39;1&#39; android:text=&#39;标题&#39;/> </RelativeLayout> <ProgressBar android:id=&#39;@+id/progressBar&#39; android:layout_width=&#39;match_parent&#39; android:layout_height=&#39;wrap_content&#39; android:layout_below=&#39;@id/rl_head&#39;/> <WebView android:id=&#39;@+id/webView&#39; android:layout_width=&#39;match_parent&#39; android:layout_height=&#39;match_parent&#39; android:layout_below=&#39;@id/progressBar&#39;></WebView> </RelativeLayout></layout>
    mWebView = bind.webView;

    需要注意的是 这里我采用的是 databinding库,这个库可以很方便 地将我们减少findViewById 的代码,同时可以将数据与我们的View 绑定在一起,是nk" target="_blank">Android支持MVVN的一个库,不了解这个库用法的用法的 请自行搜索,这里基本不涉及到这个库的 用法。

    第三步,配置webView

    如果想在当前客户端打开nk" target="_blank">浏览器的话,可以给webView 设置 setWebViewClient,并重写 shouldOverrideUrlLoading这个方法

    WebSettings settings = mWebView.getSettings();// 设置是够支持js脚本settings.setjavascriptEnabled(true);mWebView.setWebViewClient(new WebViewClient() { //重写这个方法 返回true,在当前 webView 打开,否则在nk" target="_blank">浏览器中打开 @Override public boolean shouldOverrideUrlLoading(WebView view WebResourceRequest request) { view.loadUrl(mUrl); return true; }});

    如果想显示加载进度的话,可以给webView 设置setWebChromeClient,并重写onProgressChanged()方法,至于onReceivedTitle()这个方法是拿到网页加载中的 标题

     mWebView.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view int newProgress) { super.onProgressChanged(view newProgress); // LUtils.i(&#39;newProgress=&#39; + newProgress); if (newProgress != 100) { mProgressBar.setProgress(newProgress); } else { mProgressBar.setVisibility(View.GONE); } } @Override public void onReceivedTitle(WebView view String title) { super.onReceivedTitle(view title); mTvTitle.setText(title); } });}

    想大多数APP的做法一样,如微信,按下返回键,只是想后退,并不是想销毁Activity,我们可以这样做,重写 Activity的 onkeydown()方法 ,并监听按下的键,采取 相应的 操作。

    public boolean onkeydown(int keyCode KeyEvent event) { if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) { mWebView.goBack(); return true; } return super.onkeydown(keyCode event);}

    既然有后退操作,当然也有前进操作

    //是够能够前进mWebView.canGoForward();//前进mWebView.goForward();

    第四步

    调用该方法开始加载网页

    mWebView.loadUrl(mUrl);

    到此,webView的基本用法讲解到此。


    webView 配置缓存

    配置 缓存模式

    缓存模式主要有一下几种:

    LOAD_CACHE_ELSE_NETWORK

    Use cached resources when they are available even if they have expired.(如果本地有缓存,优先使用 本地 缓存,即使已经过期了 )

    LOAD_CACHE_ONLY

    Don’t use the network load from the cache.(只使用本地 缓存)

    LOAD_DEFAULT

    Default cache usage mode.(默认的缓存 模式)

    LOAD_NORMAL

    This constant was deprecated in API level 17. This value is obsolete as from API level HONEYCOMB and onwards it has the same effect as LOAD_DEFAULT.

    LOAD_NO_CACHE

    Don’t use the cache load from the network.(不使用 本地缓存 )

    我们可以通过以下方法设置缓存模式

    WebSettings settings = mWebView.getSettings();settings.setCacheMode(WebSettings.LOAD_DEFAULT);

    webView请求错误时候的处理

    因为系统自带的 错误页面太丑了,所以我们经常会对其 进行处理,目前本人了解到的主要有两种方法
    - 加载本地的控件,显示 错误信息
    - 加载自己 定义的 html页面

    加载本地的控件

    @SuppressWarnings(&#39;deprecation&#39;)@Overridepublic void onReceivedError(WebView view int errorCode String description String failingUrl) { super.onReceivedError(view errorCode description failingUrl); if (errorCode == 404) { //用javascript隐藏系统定义的404页面信息 //String data = &#39;Page NO FOUND!&#39;; // view.loadUrl(&#39;javascript:document.body.innerHTML=&#39;&#39; + data + &#39;&#39;&#39;); mWebView.setVisibility(View.INVISIBLE); mErrorView.setVisibility(View.VISIBLE); }}

    加载 定义的 html页面

    @SuppressWarnings(&#39;deprecation&#39;)@Overridepublic void onReceivedError(WebView view int errorCode String description String failingUrl) { super.onReceivedError(view errorCode description failingUrl); if (errorCode == 404) { //用javascript隐藏系统定义的404页面信息 String data = &#39;Page NO FOUND!&#39;; view.loadUrl(&#39;javascript:document.body.innerHTML=&#39;&#39; + data + &#39;&#39;&#39;); }}

    当然实际开发中为了给用户比较还要的体验,会做非常多的处理包括有网络情况和没有网络情况的处理,对于没有网络情况的处理,这里我们跳转到打开WiFi界面,详情可以参照我的 上一篇博客android 监听网络状态的变化及实战而对于有网络情况的处理,这里我们只处理404错误,其他错误请根据项目的需求自行处理。

    @SuppressWarnings(&#39;deprecation&#39;)@Overridepublic void onReceivedError(WebView view int errorCode String description String failingUrl) { super.onReceivedError(view errorCode description failingUrl); // 没有网络连接 if (false == APP.getInstance().isConnected()) { APP.getInstance().showWifiDlg(NewsDetailActivity.this); } else { if (errorCode == 404) { //用javascript隐藏系统定义的404页面信息 String data = &#39;Page NO FOUND!&#39;; view.loadUrl(&#39;javascript:document.body.innerHTML=&#39;&#39; + data + &#39;&#39;&#39;); mWebView.setVisibility(View.INVISIBLE); } else {//其他状态码错误的处理,这里就不罗列出来了 } }}

    webView COOKIE的同步与清除

    关于这个问题,我们主要分为两步,
    - 怎样获取COOKIE
    - 怎样将COOKIE与webView进行 同步

    对于怎样获取 COOKIE,主要有以下方法

    下面只给出核心代码

    第一,使用DefaultHttpClient

    DefaultHttpClient client = new DefaultHttpClient();COOKIEStore store = client.getCOOKIEStore();List<COOKIE> list = store.getCOOKIEs();

    第二,使用HttpURLConnection

    URLConnection con= (HttpURLConnection) url.openConnection(); // 取得sessionid. String COOKIEval = con.getHeaderField(&#39;set-COOKIE&#39;); String sessionid; if(COOKIEval != null) { sessionid = COOKIEval.substring(0 COOKIEval.indexOf(&#39;;&#39;)); }

    发送设置COOKIE:

    URL url = new URL(requrl);HttpURLConnectioncon= (HttpURLConnection) url.openConnection(); if(sessionid != null) { con.setRequestProperty(&#39;COOKIE&#39; sessionid); }

    第三,使用Retrofit

    Call<ResponseBody> call = tnGouAPi.getTest(test);call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call Response<ResponseBody> response) { ResponseBody body = response.body(); Headers headers = response.headers(); Set<String> names = headers.names(); for(String key:names){ String value = headers.get(key); } try { Logger.i(&#39;onResponse: body=&#39; + body.string()); } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call Throwable t) { Logger.i(&#39;onResponse: t=&#39; + t.getMessage()); }});

    COOKIE 同步

    /** * COOKIE同步 */@SuppressWarnings(&#39;deprecation&#39;)private void syncCOOKIEToWebView(String urlList<String> COOKIEs){ COOKIESyncManager.createInstance(this); COOKIEManager cm = COOKIEManager.getInstance(); cm.setAcceptCOOKIE(true); if(COOKIEs!=null) { for (String COOKIE : COOKIEs) { cm.setCOOKIE(urlCOOKIE);//注意端口号和域名,这种方式可以同步所有COOKIE,包括sessionid } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { COOKIEManager.getInstance().flush(); } else { COOKIESyncManager.getInstance().sync(); }}

    清除COOKIE

    @SuppressWarnings(&#39;deprecation&#39;)public void clearCOOKIEs(Context context) { COOKIESyncManager.createInstance(context); COOKIEManager COOKIEManager = COOKIEManager.getInstance(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { COOKIEManager.removeAllCOOKIEs(null); } else { COOKIEManager.removeAllCOOKIE(); }}

    注意事项

    同步COOKIE要在WebView加载url之前,否则WebView无法获得相应的COOKIE,也就无法通过验证。 每次登录成功后都需要调用”syncCOOKIE”方法将COOKIE同步到WebView中,同时也达到了更新WebView的COOKIE。如果登录后没有及时将COOKIE同步到WebView可能导致WebView拿的是旧的session id和服务器进行通信。

    webView 下载文件的两种方法

    总共 有两种 方法,
    - 第一种,自己实现实现逻辑 ,下载,保存到相应目录;
    - 第二种,调用系统的下载方法

    核心代码如下

    主要是给webView设置DownloadListener监听器

     mWebView.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url String userAgent String contentDisposition String mimetype long contentLength) { //第一种下载方式是 自定义的http工具类// new HttpDownloadThread(urlcontentDispositionmimetypecontentLength).start(); //第二种下载方式是调用系统的webView具有默认的进度条 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); startActivity(intent); } });

    HttpDownloadThread

    public class HttpDownloadThread extends Thread { private String mUrl; private String mContentDisposition; private String mMimetype; private long mContentLength; public HttpDownloadThread(String url String contentDisposition String mimetype long contentLength) { this.mUrl = url; this.mContentDisposition=contentDisposition; this.mContentDisposition=mimetype; this.mContentDisposition=contentDisposition; } @Override public void run() { URL url; try { url = new URL(mUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoInput(true); conn.setDoOutput(true); InputStream in = conn.getInputStream(); File downloadFile; File sdFile; FileOutputStream out = null; if(Environment.getExternalStorageState().equals(Environment.MEDIA_UNMOUNTED)){ downloadFile = Environment.getExternalStorageDirectory(); sdFile = new File(downloadFile &#39;test.file&#39;); out = new FileOutputStream(sdFile); } //buffer 4k byte[] buffer = new byte[1024 * 4]; int len = 0; while((len = in.read(buffer)) != -1){ if(out != null) out.write(buffer 0 len); } //close resource if(out != null) out.close(); if(in != null){ in.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}

    webView的 一些扩展使用

    // 设置是否支持画面缩放settings.setBuiltInZoomControls(true);settings.setSupportZoom(true);// 设置是否显示缩放器settings.setDisplayZoomControls(false);// 设置字体的大小settings.setTextZoom(120);

    关于webView 与js互相调用的,可以 参考这一篇文章webview与javascript交互回调与异步


    题外话

    个人觉得webView还是 挺坑爹的,在不同的sdk版本中,方法修改的幅度有点多,看文档的时候经常看到许多方法过时了 webView的用法还有很多很多,这里只讲解了比较常用的,有兴趣的话了解更多的 话,请自行 阅读官方文档。不过本人建议是先掌握常用的 就OK了,以后其他需要用到的再去学就好了

    关于如何监听网络简化及处理的 ,有兴趣的可以阅读我的这一篇博客android 监听网络状态的变化及实战

    文章首发地址CSDN:http://blog.csdn.net/gdutxiaoxu/article/details/53084703

    源码下载地址:https://github.com/gdutxiaoxu/FunAPP.git


本站所有站内信息仅供娱乐参考,不作任何商业用途,不以营利为目的,专注分享快乐,欢迎收藏本站!
所有信息均来自:百度一下 (威尼斯人官网)