当前位置: 移动技术网 > IT编程>移动开发>Android > Android Webview的postUrl与loadUrl加载页面实例

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

2020年05月11日  | 移动技术网IT编程  | 我要评论

全蝎蛇蚁胶囊,湘西惊魂,西安信息网

关于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加载页面实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网