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 ...
随机推荐
- 【腾讯优测干货分享】如何降低App的待机内存(二)——规范测试流程及常见问题
本文来自于腾讯优测公众号(wxutest),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/806TiugiSJvFI7fH6eVA5w 作者:腾讯TMQ专项测 ...
- 基于Adobe Flash平台的3D页游技术剖析
写在前面 从黑暗之光,佛本是道,大战神的有插件3D页游.再到如今的魔龙之戒. 足以证明,3D无插件正在引领页游技术的潮流. 目前,要做到3D引擎,有以下几个选择. 说到这里,我们发现.这些都不重要. ...
- php修改
做出一张表,点击登录后进入此表 然后多建立一个<td></td>用来增加一列操作 <h1>英雄联盟英雄表</h1> <table width= ...
- TCP同步与异步,长连接与短连接【转载】
原文地址:TCP同步与异步,长连接与短连接作者:1984346023 [转载说明:http://zjj1211.blog.51cto.com/1812544/373896 这是今天看到的一篇讲到T ...
- asp.mvc + easyui 动态列
废话不多说,直接上代码: @model Huacisoft.Model.Crm_Sys_Role @{ Layout = null; } <!DOCTYPE html PUBLIC " ...
- 8.GitHub实战系列~8.使用GitHub建立自己的免费博客
github实战汇总:http://www.cnblogs.com/dunitian/p/5038719.html 创建一个用户名.github.io的仓库 选择设置页面风格 页面基本信息 选择一个你 ...
- Java资源大全中文版(Awesome最新版)
Awesome系列的Java资源整理.awesome-java 就是akullpp发起维护的Java资源列表,内容包括:构建工具.数据库.框架.模板.安全.代码分析.日志.第三方库.书籍.Java 站 ...
- SQL Server-聚焦INNER JOIN AND IN性能分析(十四)
前言 本节我们来讲讲联接综合知识,我们在大多教程或理论书上都在讲用哪好,哪个性能不如哪个的性能,但是真正讲到问题的实质却不是太多,所以才有了本系列每一篇的篇幅不是太多,但是肯定是我用心去查找许多资料而 ...
- 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习"模板方法模式"(Template Method Pattern)
今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知 ...
- 浅谈系列之 javascript原型与对象
在我学习与使用javascript三个月中,我一直对javascript的继承关系以及prototype理解不清,导致很多时候为什么这么用说不出个所以然来.截止到本周为止,通过之前的学习以及自己的再学 ...