在富文本中加载统一自定义视频样式,因为使用的阿里的Web播放器,
需要传一个 STS 认证信息,也就是向一段富文本字符串传参,并让前端做验证。
问题重述
我们知道 WebView Android 的传统交互方式,是通过 url 。
包括咨询一个前端同事,也说没有地址,他没办法交互,操作。
灵感还是来自(可阅《Android WebView 加载远程自定义样式(视频样式)》)之前视频样式的交互,但是那个是直接拼接,这个是方法传参交互。
解决
在富文本中通过调用前端的js方法,是可以进行交互并传参的
window.initAliplayer(${RiseWebPath.Sts})
直接将上述代码拼接到富文本中,前端再写好相应接收方法,就可以了。
/**
* 添加自定义样式
*/
private fun buildHtml(content: String): String {
var html =
"" +
"
" +"
" +"" +
"" +
"" +
"
" +"" +
"$content"+
"" +
""+
"" +
""
return html
}
亲测可用,并通过日志也看到相应方法被调用、生效。
关于监测WebView的日志信息,可阅《Android WebView 调试模式(谷歌浏览器)》
毫无征兆的bug(2018.10.17)
最初一直是使用 阿里的Web播放器播放URL的,但是后来改成了 播放 VideoId ,需要传参 STS 认证。也就是前述的传参交互。
惊闻之前可以播放的视频不能播放了,经过各种排查,发现是 Cookie 的问题。
其他项目可以展示是因为直接加载的URL,不存在 Cookie 的问题。
// 打印WebView日志,发现报错
Failed to set the 'cookie' property on 'Document': Cookies are disabled inside 'data:' URLs.
也就是阿里加密播放需要 Cookie。然后各种拙劣手段,添加 Cookie,没有什么用。
最后时刻
我是使用 loadData 加载的
loadData(buildHtml(content), "text/html; charset=UTF-8", null)
更改为 loadDataWithBaseURL ,传入baseUrl & historyUrl
(因为我是富文本,没有url,就随意写的,然而竟可以!)
loadDataWithBaseURL(RiseWebPath.TaskBaseUrl,buildHtml(content),"text/html; charset=UTF-8", null,"")
我们知道 loadDataWithBaseURL 原本是为了优化加载速度,第二次加载时可以根据 baseUrl & historyUrl 类似增量加载,以提高加载速度。
然而,竟然可以给一段富文本添加 任意的baseUrl & historyUrl ,来解决 Cookie 问题,是我始料未及的。特此记录!
始料未及的事有很多,比如STS过期(2018.10.18)
上述方案,顺利传递过去 STS 后发现,更悲催的事情是 阿里播放器STS有效时间只有1小时。也就是要走上 监听过期 >> 重新获取STS >> 再次传参(WebView重新加载内容)的不归路
而且,频率是每小时。这显然是不可接受的。
方案
让前端通过JS自己获取 STS,然后验证是否过期,然后重新初始化阿里播放器
问题是没有地址,前端可以请求接口吗?能够获取 STS 吗?
答案是可以的!只要我们把地址给前端传过去。
// 传给前端 接口地址,以让其自己更新sts,保证正常播放
val GraphQlUrl = "${BuildConfig.BASE_URL}graphql/"
graphql 也支持直接用地址请求
/**
* 添加自定义样式
*/
private fun buildHtml(content: String): String {
var html =
"" +
"
" +"
" +"" +
"" +
"" +
"" +
"" +
"
" +"$content"+
""+
"" +
""
return html
}
一波三折,但长见识...
うずまき ナルト