Android Webview的postUrl与loadUrl加载页面实例

关于Android的webview,用过的想必都不会陌生。这里我就不说webview的基本用法了,想要知道的可以去网上百多,有很多介绍webview基本用法的。

本文要介绍的主要是在项目过程中使用webview的postUrl遇到的坑。

1、使用场景如下:

webview在加载H5链接时,默认是使用loadUrl进行加载,如果你设置了缓存属性(进行缓存),在显示的H5页面内点击跳转到另外一个页面后,按回退键,可以正常的返回到上一个页面,因为进行了缓存设置。但是如果使用postUrl进行加载,即使你设置的缓存属性是进行设置,当你调转到另外一个页面后,按回退键,不会缓存之前的页面,而是重新调用postUrl进行加载。这时问题就来了,同样是进行加载,第一次的postUrl能够正常加载,重新加载会加载失败,没有内容显示。是不是很有意思,为什么会出现这样的情况呢,通过抓包发现,虽然加载的是同样一个链接,但是重新加载的请求属性为空,导致加载失败。

2、如何解决:

既然找到了原因,请求属性为空,肯定是有解决办法的,那就手动设置请求属性,重新加载。如何手动设置,首先你肯定是要能够拿到请求的所有内容和参数。用过webview的人相必都很熟悉它的setWebViewClient方法。该方法内部有shouldInterceptRequest方法能够拿到请求的所有内容。不多说了,先上代码。

public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
  if(Build.VERSION.SDK_INT >= 21){
   if(!request.getMethod().equalsIgnoreCase("post")){
    return super.shouldInterceptRequest(view, request);
   }
  }
  DataOutputStream os = null;
  try {
   URL mUrl = new URL(url);
   HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection();
   connection.setDoInput(true);
   connection.setDoOutput(true);
   connection.setUseCaches(false);
   connection.setRequestMethod("POST");
   if(Build.VERSION.SDK_INT >= 21){
    Iterator headerKeys=request.getRequestHeaders().keySet().iterator();
    while(headerKeys.hasNext()){
     String key=headerKeys.next();
     connection.setRequestProperty(key,request.getRequestHeaders().get(key));
    }
   }
   connection.setRequestProperty("content-type","application/x-www-form-urlencoded");
   os = new DataOutputStream(connection.getOutputStream());

   os.write(EncodingUtils.getBytes(postData, "BASE64"));
   os.flush();
   return new WebResourceResponse("text/html", connection.getContentEncoding(), connection.getInputStream());
  } catch (Exception e) {
   e.printStackTrace();
  }finally {
   if(os!=null){
    try {
     os.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
  return super.shouldInterceptRequest(view, request);
 }
});

webView.postUrl(url, EncodingUtils.getBytes(postData, "BASE64"));

该方法有个缺陷,只在Android 5.0.0以上的Api才有,5.0.0以下的Api是没有此方法的,这也是一个坑,不能兼容所有机型。通过该方法中的setRequestProperty方法重新设置了请求属性,然后使用postUrl进行重新加载,可以解决按回退键后页面的重新恢复。注意,由于post加载是不能缓存的,因此在设置缓存属性时一定要设置成重新加载属性。

3、解决后出现的问题:

问题看似解决了,但是此方法会有坑。如果你仔细研究该方法,你会发现shouldInterceptRequest方法是在整个加载过中都调用了的。如果你进行抓包,你会发现,从开始加载链接到H5页面中加载的每一个请求,该方法都会被调用,简单的说就是有多少个请求,该方法就会调用多少次。如果你的页面中还有一次post请求,那么问题就来了,你需要将第二次post请求的请求内容与第一次的进行对比,对比后选择到底是加载第一次的页面,还是加载第二次的页面,否则就会默认加载第一次的post页面。

4、结论

webview的H5页面加载最好使用loadUrl方式,如果使用postUrl方式进行加载,你需要重写整个setWebViewClient方法,当中会出很多坑,不建议这样做。

以上这篇Android Webview的postUrl与loadUrl加载页面实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 关于WebView 重定向行为导致的多次加载的问题

    使用 WebView 时,我们通常会重写以下方法: shouldOverrideUrlLoading() onPageStarted() onPageFinished() 一.WebView 内部点击连接,他们的回调顺序是这样的: 1.如果是固定的地址: shouldOverrideUrlLoading() -> onPageStarted()-> onPageFinished() shouldOverrideUrlLoading()由于它要提供给APP选择加载网页环境的机会,所以只要是网页上

  • android WebView加载html5介绍

    Android设备多分辨率的问题 Android浏览器默认预览模式浏览 会缩小页面 WebView中则会以原始大小显示 Android浏览器和WebView默认为mdpi.hdpi相当于mdpi的1.5倍 ldpi相当于0.75倍 三种解决方式:1 viewport属性 2 CSS控制 3 JS控制 1 viewport属性放在HTML的<meta>中 Html代码 复制代码 代码如下: <SPANstyle="FONT-SIZE: x-small"> <

  • Android中的webview监听每次URL变化实例

    通过这个可以监听Android中webview访问的URL变化: webView.setWebViewClient(new WebViewClient(){ @Override public void onLoadResource(WebView view, String url) { Log.e("hao","WebView3:"+view.getUrl()+"\\n"+" URL3:"+url); super.onLoad

  • Android Webview的postUrl与loadUrl加载页面实例

    关于Android的webview,用过的想必都不会陌生.这里我就不说webview的基本用法了,想要知道的可以去网上百多,有很多介绍webview基本用法的. 本文要介绍的主要是在项目过程中使用webview的postUrl遇到的坑. 1.使用场景如下: webview在加载H5链接时,默认是使用loadUrl进行加载,如果你设置了缓存属性(进行缓存),在显示的H5页面内点击跳转到另外一个页面后,按回退键,可以正常的返回到上一个页面,因为进行了缓存设置.但是如果使用postUrl进行加载,即使

  • Android 自定义view实现进度条加载效果实例代码

    这个其实很简单,思路是这样的,就是拿view的宽度,除以点的点的宽度+二个点 之间的间距,就可以算出大概能画出几个点出来,然后就通过canvas画出点,再然后就是每隔多少时间把上面移动的点不断的去改变它的坐标就可以, 效果如下: 分析图: 代码如下: package com.example.dotloadview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bit

  • Android App中实现图片异步加载的实例分享

    一.概述 一般大量图片的加载,比如GridView实现手机的相册功能,一般会用到LruCache,线程池,任务队列等:那么异步消息处理可以用哪呢? 1.用于UI线程当Bitmap加载完成后更新ImageView 2.在图片加载类初始化时,我们会在一个子线程中维护一个Loop实例,当然子线程中也就有了MessageQueue,Looper会一直在那loop停着等待消息的到达,当有消息到达时,从任务队列按照队列调度的方式(FIFO,LIFO等),取出一个任务放入线程池中进行处理. 简易的一个流程:当

  • Android下拉刷新上拉加载控件(适用于所有View)

    前面写过一篇关于下拉刷新控件的文章下拉刷新控件终结者:PullToRefreshLayout,后来看到好多人还有上拉加载更多的需求,于是就在前面下拉刷新控件的基础上进行了改进,加了上拉加载的功能.不仅如此,我已经把它改成了对所有View都通用!可以随心所欲使用这两个功能~~ 我做了一个大集合的demo,实现了ListView.GridView.ExpandableListView.ScrollView.WebView.ImageView.TextView的下拉刷新和上拉加载.后面会提供demo的

  • Android编程实现压缩图片并加载显示的方法

    本文实例讲述了Android编程实现压缩图片并加载显示的方法.分享给大家供大家参考,具体如下: 解析: 图片压缩的关键就是 options.inSampleSize = scale; 如果scale > 0,表示图片进行了压缩 /** * 压缩图片 * @author chen.lin * */ public class LoadImageActivity extends Activity implements OnClickListener { private Button mBtnLoad;

  • Android插件化之资源动态加载

    Android插件化之资源动态加载 一.概述 Android插件化的一个重要问题就是插件资源访问问题,先列出会面对的问题 1.如何加载插件资源 2.如何处理插件资源与宿主资源的处突:插件化资源问题要做到的效果是,如果我们要获取的资源在插件中找得到,则加载优先加载插件的,如果找不到,则到宿主资源中找.这样能做到动态更新的效果. 3.如何确保插件和宿主使用到的是被修改过的资源. 二.原理分析 在做一件事之前必须先弄清楚原理,所以,这里先要弄清楚Android的资源体系原理. 1.资源链 Contex

  • Android自定义view实现阻尼效果的加载动画

    效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又称减幅振动.衰减振动.[1] 不论是弹簧振子还是单摆由于外界的摩擦和介质阻力总是存在,在振动过程中要不断克服外界阻力做功,消耗能量,振幅就会逐渐减小,经过一段时间,振动就会完全停下来.这种振幅随时间减小的振动称为阻尼振动.因为振幅与振动的能量有关,阻尼振动也就是能量不断减少的振动.阻尼振动是非简谐运

  • Android使用PullToRefresh实现上拉加载和下拉刷新效果的代码

    在没给大家介绍正文之前,先给大家介绍展示下运行图,如果大家感觉还不错,请继续往下阅读: 相关阅读:分享Android中pullToRefresh的使用心得 项目已同步至:https://github.com/nanchen2251/pullToRefreshDemo 简单使用详情: 1)studio可以直接在app的module设置中直接进行搜索,但是有-的必须添上,而不能用空格代替,为了更加了解这个东西,我还是推荐大家去这里看看,奉上网址: https://github.com/chrisba

  • Android自定义View实现loading动画加载效果

    项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. 先自定义一个View,继承自LinearLayout,在Layout中,添加布局控件 /** * Created by xiedong on 2017/3/7. */ public class Loading_view extends LinearLayout { private Context m

  • Android开发实现自定义新闻加载页面功能实例

    本文实例讲述了Android开发实现自定义新闻加载页面功能.分享给大家供大家参考,具体如下: 一.概述: 1.效果演示: 2.说明:在新闻页面刚加载的时候,一般会出现五种状态 未知状态(STATE_UNKNOW).空状态(STATE_EMPTY).加载中(STATE_LOADING).错误(STATE_ERROT).成功(STATE_SUCCESS) 因为每个Detail页面都会出现,所以我们可以把他们封装成一个LoadPage的自定义view,可以复用 二.实现: 1.首先的定义三个布局,为什

随机推荐