Android WebView 302斗争之旅
一.背景
越来越多的业务接入,项目内多多少少会出现几个H5页面,只是单纯的提供WebView容器接入H5页面根本满足不了需求,他们需要登录态,需要制定协议控制Native的导航栏,或者需要JsBridge做一些更复杂的操作,这篇主要讲登录态出现的问题。
二.涉及的知识
Android WebView加载url的时候,我们是这样做监听的:
- 页面加载前会回调onPageStarted
- 页面加载完成会回调onPageFinished
- 当页面加载前且在onPageStarted后会回调shouldOverrideUrlLoading让我们决定是否自己处理这个url
public class PerformanceWebClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
}
三.自定义返回栈
14年最初接触的项目,WebView页面是需要登录态的,处理方式就是shouldOverrideUrlLoading方法中,直接将url后面拼入参数,return true告知WebView组件url我们已经处理,你不用管了。
public class PerformanceWebClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("http") || url.startsWith("https")) {
view.loadUrl(appendParamsToUrl(url));
return true;
} else if (isScheme(url)) {
return true;
}
return false;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
}
简单的代码结构大致是这样,但是迅速暴露出一个问题:302页面返回栈。
我们主动load的页面会加入到返回栈内,而当我们webview.goBack()的时候,加载的时候还是一个302,导致无法正常关闭页面。
这时想到一个方法,自己定义返回栈。
问题是,一个url入栈的标准是什么?
举一个栗子:
A==302==>B==302==>C
加载A的url查看回调顺序是:
onPageStartedA==>onPageStartedB==>onPageStartedC==>onPageFinishedC
从这个角度来看,貌似onPageFinished中将url作为已加载的url挺靠谱的,但是现在存在一个问题,我每次回退栈都要以重新load的形式刷新页面,性能和流量都有耗费。
还存在一个问题,在实际情况中遇到,某一个业务url加载形式例如:
A==302==>B==302==>C==302==>D
加载A的url查看回调顺序是这样的:
onPageStartedA==>onPageStartedB==>onPageStartedC==>onPageFinishedC==>onPageStartedD==>onPageFinishedD
C页面是302到D的,但是也走了onPageStarted方法,猜测是做了某些操作再主动重定向的,这种url我们也不希望加入返回栈内,但是我们不能准确的检测到。
四.尝试优化
在后来接手的另一个项目中,也存在了302返回栈的问题,既要保留登陆态,又需要302不加入返回栈。
这时看到一个这样的处理方式:
class MerchantOnTouchListener implements View.OnTouchListener {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
try {
WebView.HitTestResult hr = ((WebView) view).getHitTestResult();
if (hr != null && mLastUrl != null) {
switch (hr.getType()) {
case WebView.HitTestResult.SRC_ANCHOR_TYPE:
case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
break;
case WebView.HitTestResult.UNKNOWN_TYPE:
return true;
break;
default:
return false;
}
if (previous.isEmpty() || !previous.get(previous.size() - 1).equals(mLastUrl)) {
previous.add(mLastUrl);
}
}
} catch (Exception ignored) {
}
return false;
}
}
当我们触摸屏幕时(通常就是开始点击链接)使用HitTestResult去看状态,如果得到的type是链接跳转类型,那么将最后加载的url加入返回栈。
实际效果是:302被避免了,但是页面内如果触摸的地方url有变化(比如params变了)也会加入返回栈,回退次数还是增加了,而且解决不了重新加载的问题。
就在这时得知了最开始接触的项目更换了登陆方式,App的登陆就是H5页面,登陆成功后拿到Cookie,Cookie既可以给Native访问Api使用,也可以在H5页面做登录态使用,页面栈全部交给WebView容器处理。
以为这就结束了么?
但是又出现了一个问题:运营商劫持
国内的网络环境大家比较了解,Headers的丢失率比较高,丢失了Cookie就等于丢失了登陆状态,这是其中一点;其次是如果业务发展已经很庞大,很难从Native Token 走SSO的方式转化为Cookie方式。
五.总结
目前经历了几个项目,一直没有很优雅的解决302的问题,目前的做法也有一些瑕疵,希望在以后的工作中能找到更好的方法。
Android WebView 302斗争之旅的更多相关文章
- webview之如何设计一个优雅健壮的Android WebView?(上)(转)
转接:https://iluhcm.com/2017/12/10/design-an-elegant-and-powerful-android-webview-part-one/ 前言 Android ...
- 如何设计一个优雅健壮的Android WebView?(上)
转:如何设计一个优雅健壮的Android WebView?(上) 前言 Android应用层的开发有几大模块,其中WebView是最重要的模块之一.网上能够搜索到的WebView资料可谓寥寥,Gith ...
- Android WebView useragent
今天介绍一下Android WebView UserAgent, User-Agent(简称UA)是HTTP请求头部用来标识客户端信息的字符串, 包括操作系统, 浏览器等信息.为了建立手机客户端的信息 ...
- android webview开发问题及优化汇总
我们在native与网页相结合开发的过程中,难免会遇到关于WebView一些共通的问题.就我目前开发过程中遇到的问题以及最后得到的优化方案都将在这里列举出来.有些是老生常谈,有些则是个人摸索得出解决方 ...
- Android WebView 开发教程
声明在先:必须在AndroidMainfest.xml 里面声明权限,否则在Java里面编写的所有WebView浏览网页的代码都无法正常使用 <uses-permission android:n ...
- [Android] WebView内的本地网页,使用XMLHttpRequest读取本地档案
[Android] WebView内的本地网页,使用XMLHttpRequest读取本地档案 问题情景 在Android里,可以使用WebView来呈现本地或是远程的网页内容.但是在显示本地网页时,如 ...
- Android webview通过http get下载文件下载两次的问题及解决方法
一.现象 一般通过Android webview进行下载文件的方法是 1.重写DownloadListener的onDownloadStart方法,在onDownloadStart方法中弹出对话框提示 ...
- Android WebView常见问题及解决方案汇总
Android WebView常见问题解决方案汇总: 就目前而言,如何应对版本的频繁更新呢,又如何灵活多变地展示我们的界面呢,这又涉及到了web app与native app之间孰优孰劣的争论. 于是 ...
- android webview 底层实现的逻辑
其实在不同版本上,webview底层是有所不同的. 先提供个地址给大家查:http://grepcode.com/file/repository.grepcode.com/java/ext/com.g ...
随机推荐
- .NET跨平台之旅:在生产环境中上线第一个运行于Linux上的ASP.NET Core站点
2016年7月10日,我们在生产环境中上线了第一个运行于Linux上的ASP.NET Core站点,这是一个简单的提供后端服务的ASP.NET Core Web API站点. 项目是在Windows上 ...
- 海量数据处理利器greenplum——初识
简介及适用场景 如果想在数据仓库中快速查询结果,可以使用greenplum. Greenplum数据库也简称GPDB.它拥有丰富的特性: 第一,完善的标准支持:GPDB完全支持ANSI SQL 200 ...
- Struts2+Spring+Hibernate框架整合总结详细教程
一.SSH三大框架知识总结 Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架.其全新的Struts 2的体系结构与S ...
- Java设计模式之代理模式(Proxy)
前言: 最近在研究Retrofit开源框架的时候,其主要核心代码是通过注解标示参数,动态代理模式实现具体接口,反射机制进行参数解析,最终实现发送请求.其实之前在学习Xutils源码的时候,Xutils ...
- SharePoint 2013 configure and publish infopth
This article will simply descript how to configure and publish a InfoPath step by step. Note: To con ...
- Oracle使用SQL传输表空间
源环境:RHEL 6.4 + Oracle 11.2.0.4 目的环境:RHEL 6.4 + Oracle 11.2.0.4 DG双机 要求:使用SQL传输表空间DBS_D_JINGYU从源环境到目的 ...
- 分布式系统理论进阶 - Raft、Zab
引言 <分布式系统理论进阶 - Paxos>介绍了一致性协议Paxos,今天我们来学习另外两个常见的一致性协议——Raft和Zab.通过与Paxos对比,了解Raft和Zab的核心思想.加 ...
- 现代3D图形编程学习-基础简介(2) (译)
本书系列 现代3D图形编程学习 基础简介(2) 图形和渲染 接下去的内容对渲染的过程进行粗略介绍.遇到的部分内容不是很明白也没有关系,在接下去的章节中,会被具体阐述. 你在电脑屏幕上看到的任何东西,包 ...
- “全能”选手—Django 1.10文档中文版Part1
本文是博主翻译的Django1.10版本官方文档的第一部分,如时间充裕,争取一直翻译下去,经验不足,或有错漏,敬请指正. 另外对于公开文档进行翻译的版权问题不是很清楚,如有侵权请联系我! 另外,要转载 ...
- 卷积神经网络提取特征并用于SVM
模式识别课程的一次作业.其目标是对UCI的手写数字数据集进行识别,样本数量大约是1600个.图片大小为16x16.要求必须使用SVM作为二分类的分类器. 本文重点是如何使用卷积神经网络(CNN)来提取 ...