android webview可以输入字符串,Android Webview的一些坑

Android Webview的一些坑

前言

Webview在开发中,总会遇到各种兼容,崩溃,支持各种功能的问题。这里整理下我们是如何处理这些问题的。这里不会说怎么开发一个基本的功能,像这样的文章应该有很多。这里会罗列一些我自己认为很有用的功能的实现,或者一些常见的问题。

带#号的url拼接参数

由于uri的格式问题,scheme://[path]?[param]#[fragment]

参数肯定是只能拼接到?号后方和#号前方的。

两种方法处理。

1、转化为uri,使用uri的api来拼接参数

2、自己处理字符串,通过“#”分为两部分,在第一部分上拼接参数

重载和回退问题

M页内部跳转的时候,有时候不希望返回上一个页面。因此在url上拼接特定的参数,如果检测到了这样的参数,直接跳过这条历史记录,返回上上个页面。

在一次域名升级过程中,FE通过replace方法替换了加载的域名,这时候页面会进行重载,在Android系统中,这个重载会在历史栈中留下记录,因此返回之后会回到原地址,然后又跳到新地址。造成问题。由于在旧的地址中参数不太切合实际(入口无法统计,替换难度工作量巨大。不可能全换掉。),因此在跳转后的url中拼接参数标记这是被替换的,上一个地址应该被忽略。因此有了这样的操作。

下面是对goBack的处理逻辑。

private void goBack(WebView webView) {

if (webView == null) {

return;

}

WebBackForwardList temp = webView.copyBackForwardList();

if (temp == null) {

webView.goBack();

return;

}

int cIndex = temp.getCurrentIndex();

WebHistoryItem item = temp.getItemAtIndex(cIndex);

int i;//需要退到的页面

i = cIndex - 1;

//isReplaced的url需要回退

while (item != null && StringUtils.isNotEmpty(item.getUrl())

&& item.getUrl().contains("isReplaced=1")) {

item = temp.getItemAtIndex(i);

i = i - 1;

}

//跳过url中包含isGoBack=1的链接,表示这个url不会进入回退列表

for (; i >= 0; i--) {

String url = temp.getItemAtIndex(i) == null ? null : temp.getItemAtIndex(i).getUrl();

if (!StringUtils.isNullOrEmpty(url) && (url.contains("isGoBack=1") || url.startsWith("data:text/html"))) {

if (i == 0 && getActivity() != null) {

//如果需要back的页面是not go back ,并且当前页面是最后一页 ,那么关闭activity

getActivity().finish();

return;

}

continue;

}

break;

}

if (i < 0 && getContext() != null) {

getActivity().finish();

return;

}

//往前back

webView.goBackOrForward(-cIndex + i);

}

返回拦截弹窗

在M页有时候会需要需要用户输入,通常情况下,用户误点击了返回之后就直接退出了这个页面。因此提供了一个可以让M页设置返回弹窗的功能。

具体做法就是通过提供JS入口,让FE可以设置返回弹窗。然后页面关闭之前判断是否有弹窗逻辑来进行拦截。

实现无TitleBar,穿透顶栏

有时候UI上会有一些要求,让M的标题栏特殊些或者穿透顶栏,或者没有标题栏之类的。

我们的处理是根据url中拼接的参数来决定这个页面的标题栏的样式或者隐藏,来决定是否穿透顶栏。

M页侧获取到的宽度为0

由于我们实现了离线包的功能,所以获取资源的速度很快。

后来发现部分页面加载的时候仅剩下了图片,没有文字。

客户端排查问题,发现页面加载完成的时候,实际上webview的宽度还是为0。

解决方案,webview布局到页面上的时候才去加载url。

mWebView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

if (mWebView != null) {

loadUrl(mUrl);

mWebView.getViewTreeObserver().removeOnGlobalLayoutListener(this);

}

}

});

微信支付返回商家信息不一致的问题

一次我们收到其他业务线说在android上无法用微信的M页支付问题,经查明是因为Referer不一致导致,后来发现大部分android手机的Webview默认都不会带referer,因此造成了问题。这里在shouldOverrideUrlLoading的时候,加载新的url的时候添加进去Referer,这样就没有问题了。

Map additionalHttpHeaders = new HashMap();

additionalHttpHeaders.put("Referer", view.getUrl());

mWebView.loadUrl(url, additionalHttpHeaders);

魅族手机打开文件选择的问题

有些魅族机型在打开系统的选文件功能的时候会崩溃,说没有读取uri的权限,因此在启动M页的时候需要添加这样的权限。

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

其他

还有其他的一些功能很实用,一般都是M页通用的能力。比如全屏播放视频,选图,选文件,拍照,拍视频。这里说的是系统再带的功能。只需按照规范来实现功能就可以了。

结尾

还有一些对ssl的处理了,js的调用,js的调用前域名鉴权。这里不再说了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值