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

作者:爅烆 时间:2021-06-26 19:39:04 

关于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方法,当中会出很多坑,不建议这样做。

来源:https://blog.csdn.net/AXJ1991/article/details/78459781

标签:Android,Webview,postUrl,loadUrl
0
投稿

猜你喜欢

  • SpringBoot可视化监控的具体应用

    2023-07-28 20:32:02
  • java IO流 之 输出流 OutputString()的使用

    2023-08-11 23:16:30
  • Java开发微信公众号接收和被动回复普通消息

    2022-04-07 12:30:44
  • 如何使用SpEL表达式实现动态分表查询

    2022-01-05 03:09:55
  • Unity3D游戏开发数据持久化PlayerPrefs的用法详解

    2022-11-11 23:16:00
  • svn 清理失败 (cleanup 失败) 的快速解决方法

    2022-10-25 11:22:40
  • 使用Springboot封装一个自适配的数据单位转换工具类

    2022-06-07 07:12:14
  • selenium+java破解极验滑动验证码的示例代码

    2022-11-19 21:52:01
  • C#调用WebService实例开发

    2022-11-21 22:51:08
  • Android性能之冷启动优化详析

    2022-03-06 13:42:51
  • Spring与Shiro整合及加载权限表达式问题

    2023-10-01 09:29:50
  • java实现马踏棋盘的算法

    2023-11-29 17:00:29
  • C# 系统热键注册实现代码

    2021-10-07 00:12:14
  • Java实现飞机航班管理系统的思路详解

    2022-08-20 19:48:42
  • Springboot-admin整合Quartz实现动态管理定时任务的过程详解

    2023-08-26 03:01:07
  • Java数据结构之环形链表和约瑟夫问题详解

    2023-07-19 11:02:32
  • Spring AOP与AspectJ的对比及应用详解

    2022-07-07 12:50:47
  • C#生成word记录实例解析

    2023-09-10 00:17:33
  • Java 用反射设置对象的属性值实例详解

    2023-11-26 03:56:51
  • 浅谈java异常处理之空指针异常

    2022-07-31 03:12:27
  • asp之家 软件编程 m.aspxhome.com