Android与JavaScript交互数据上限(Base64图片传输问题)

使用webview.loadUrlJavaScriptBase64格式的较大图片时,有的Android版本上不反馈任何错误信息,只是页面接收不到任何信息,传入的脚本不执行任何操作。

有的则报错,如下:

如下图:


2097152字节/1024/1024 = 2 兆,这说明调用 loadUrl,最多只能传2M的内容

Base64是将原文按照每3个字节一组分开,这个3字节组中的每一组将被按照位分解成4个部分,每个部分6个位,在这4个部分的每个部分高位加上20构成一个新的4字节组,新的字节组中,每个字节只有6位,能表示64个值。

如果原文不是三字节的倍数,可能多出一个字节和两个字节,分别会被转为2字节和3字节的BASE64编码,这时编码系统应该在形成的BASE64编码最后添加上填充符”=”,保证BASE64编码长度是4的倍数。所以在BASE64编码后添加的填充符”=”可能为0-2个。

2兆 / 4 * 3 = 1.5兆,所以传给JavaScript的图片最多不能超过1.5兆

webview.evaluateJavascript

通过下面代码进行打印,可以发现evaluateJavascript加载大于5兆的图片均正常

但是,当“字符串常量”替换成“Base64”的图片数据时,却报错了

我就想,会不会是由于Base64的转换过程中,有某些特殊字符,导致evaluateJavascript无法解析

下面是图片转Base64的方法,FLAGS用的是默认的Base64.DEFAULT

Base64的前10位和后10位进行拼接,同样用console.log打印出来,发现正常。

再看一下打印,突然发现打印出来的Base64有换行符

这是因为Base64.DEFAULT,当字符串长度超过76会自动添加换行符,将Base64FLAGS改成Base64.NO_WRAP,再跑一遍,可以了 ~ ~

3.5兆多的图片,可以被前端正常获取并显示了。

但是注意,传大图给前端要花很长的时间!!!

因为它需要将图片数据按字节做一次转换,然后前端获取之后设置到属性里,显示的时候需要再转一次(混合开发内耗严重),加载一张图片,要让用户等很久,体验很差。

因此建议的做法是,图片压缩之后传给前端,然后要上传时,直接调用Android接口,从本地上传

最大限制

即使使用了webview.evaluateJavascript也不是可以无限制的传递数据。如果数据太大,也会导致OOM

java获取不到可用的内存上限。
网上有activityManager.getMemoryClass()runtime.totalMemory()但是这些都是不能用来进行判断的,解决方案一般只有分片上传。

参考链接


Android 与 JS 交互数据上限(Base64图片传输问题)

发布者

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注