Flutter 静态挂载腾讯X5WebView(Tbs)浏览器内核 您所在的位置:网站首页 正在加载腾讯X5内核 Flutter 静态挂载腾讯X5WebView(Tbs)浏览器内核

Flutter 静态挂载腾讯X5WebView(Tbs)浏览器内核

2024-07-09 10:38| 来源: 网络整理| 查看: 265

文章目录 背景一、寻找Android WebView 内核替换方案(在native层面验证)1.CrossWalk2.腾讯X5浏览器1)动态集成2)静态集成 二、Flutter 静态集成的X5WebView 的插件开发1.StaticTBS Flutter Plugin(插件) 开发1)创建Flutter Plugin2)编写Android Native代码3)编写Flutter插件代码 三、集成插件项目的编译1. 针对“Shrink”做的修改2.so库打包机制 总结

背景

项目中(Flutter项目)有一个需求是通过webview加载界面,来显示实时视频(webrtc),那么问题是,不同Android手机浏览器对于webrtc视频解码的支持性有差异导致部分手机无法正确显示视频,部分手机只有声音没有视频。那么我决定通过端侧来解决这个问题(我猜测修改web端代码进行适配也能解决),由此引申出了这篇文章,留作参考记录。涉及到的主要知识点如下:

Android 平台下替换浏览器内核方案。Android Native 静态集成腾讯X5(tbs)浏览器内核。(需要原生静态集成tbs浏览器内核的同学同样适用)Flutter plugin 插件开发。Flutter 打包机制。 一、寻找Android WebView 内核替换方案(在native层面验证) 1.CrossWalk

经过测试,最新版本的CrossWalk并不能解决问题,仍然存在视频无法解码的问题。集成方式不再多说,相关教程很多。要注意的是crosswalk webview 想要略过ssl验证,需要修改源码中的SslUtil文件,修改为如下,直接忽略掉ssl异常。

public static boolean shouldDenyRequest(int error) { if (error >= -214 && error case -213: case -212: case -211: case -208: case -207: case -206: case -203: case -202: case -201: case -150: case -129: return false; default: return false; } } else { throw new AssertionError(); } }

然后将这个java文件编译成".class"文件后,替换到crosswalk的aar包中。我在验证过程中也做了一些工作,把用到的资源分享一下,以便有同学用得到,下面的下载链接是编译成.class的SslUtil文件(其实这个是比较难搞的),将内核的aar sdk解压替换即可,可以到crosswalk官网自行下载32or64位的sdk。 下载链接 提取码:8cy5

2.腾讯X5浏览器

另外一个方案是腾讯的X5浏览器内核(https://x5.tencent.com/),经测试,可以解决我的问题,兼容性良好,有两种集成方式说明一下

1)动态集成

动态集成具体方式官网上&其他帖子有很多说明,自行查找。经过测试,动态集成在Native项目中,内核挂载还算相对稳定(也有反复挂载不成功的情况),但是已Flutter 插件(Flutter 插件为静态集成)的方式,集成到Flutter项目后,体验非常之差,内核挂载成功率很低。所以动态集成方案pass,无法使用。(说句题外话,虽然这里只写了一段,但是验证过程确实还是用了一些时间的)

2)静态集成

那么目前就明确了两点,要解决两个问题,首先是采用x5Webview替换内核方案,其次是需要静态集成。

参考文章 原生项目需要静态集成的同学对照这篇文章集成即可。

我这里补充一下我提取到到的64位内核资源(实际提取不难但我觉得麻烦,其实用32位的so文件足够),下载链接如下: 下载链接 提取码:fmy5

到此,这两个问题圆满解决。

二、Flutter 静态集成的X5WebView 的插件开发

明确了方案,并且tbs静态集成也ok,那么下一步就是要创建一个静态集成的X5WebView的Flutter插件给Flutter项目使用,搜索了一下目前只有x5webview动态集成的flutter插件,那么这里就需要自己去搞一个插件来用,这里我借鉴了pub上已有的动态继承tbs的库。 插件提供了两种使用方式,一种是直接从Flutter界面跳转到Native方式使用了Tbs浏览器的Activity,一种是直接使用实现了TbsWebView的Flutter Widget

1.StaticTBS Flutter Plugin(插件) 开发 1)创建Flutter Plugin

as中,点击File->New->New Flutter Project ,弹出选择项目类型界面,选择Flutter Plugin,点击Next,之后填写相应信息,最后finish,完成创建。创建的项目中内含一个example目录(是一个flutter 项目),这个是用来调试plugin功能的,可作为临时宿主使用。

2)编写Android Native代码

这点比较关键的,我想通过android studio 开发原生部分的代码,关键点是,先要构建一下生成的eample项目,cd 到 example目录,执行“flutter build apk ”即可,构建完成(是否成功不重要),之后就可以通过android studio 打开项目进行native开发,要注意的是,要打开example里面的android项目。

plugin project结构 将提取到的armeabi架构的tbs so库文件以及,静态加载用到的jar包导入项目。

3)编写Flutter插件代码

这里涉及到的代码以及知识点较多,主要是插件开发相关,后面我也许会单独写文章记录,就不在这单独讲解了,可以搜索Flutter Plugin插件开发相关文章,目前项目已上传到git,请自行查看 插件项目地址

三、集成插件项目的编译

使用静态tbs插件后,直接打包还是会发现内核挂载失败,核心问题就是我目前还没有提取到不同架构下的tbs so库,只提取到了armeabi架构的,受限于tbs挂载规则或者是flutter so加载机制,tbs的armeabi so库并不能向上兼容,放在armeabi-v7下不不好用。只能放到armeabi文件加下才可以保证加载成功,所以还需要关注一下下面的说明

1. 针对“Shrink”做的修改

当项目集成了静态内核,会发现还是无法挂载,是因为flutter的打包apk机制 ,进行了“shrink”操作,将“com.tencent.cmtt” 包下的“utils”文件夹给“优化”掉了,误伤友军,所以为了能正常挂载静态内核,那么需要对flutter gradle文件进行修改。

Flutter 本身gradle的文件路径 : D:\你的flutter本地源码文件夹\flutter_windows_v1.9.1+hotfix.6-stable\flutter\packages\flutter_tools\gradle

打开这个路径下的“flutter.gradle” 文件进行修改,修改这个部分代码,将注释部分屏蔽掉,这样flutter工程在打包anroid项目的时候,就不会去shrink,对apk进行瘦身了,这里要注意,如果修改了flutter源码下的代码,后面想要通过“flutter upgrade”升级版本的时候会出错,需要先revert掉,才可以正常升级。

private static Boolean shouldShrinkResources(Project project) { //将这个函数屏蔽掉 if (project.hasProperty("shrink")) { return project.property("shrink").toBoolean() } return false } 2.so库打包机制

接下来要讲一下到Flutter so 库打包机制了,这里会延伸出一个flutter常见问题“couldn’t find “libflutter.so””,特别是你通过命令行进行打包的时候更容易出现这个问题,原因稍后讲解。 当解压正常的Flutter apk包,我们可以看到lib下的armeabi,arm64-v8a,x86等文件夹下会有“libflutter.so”以及“libapp.so”这两个文件,可以这样理解,libapp.so他就是我们用flutter写的业务逻辑所打包的产物,libflutter.so实际上可以理解为libapp.so执行所必备的环境之一,正常运行的时候根据手机架构加载对应的so库,达到native层面优化的效果。 那么回到上面的问题上来,“couldn’t find "libflutter.so”导致崩溃,极大概率就是你使用了一些plugin,或者是引用了一些第三方库文件,打包时导致slibflutter.so库没有被打到指定的文件夹下,导致应用崩溃,如果是libapp.so没有被打进去,应用只是会白屏,因为找不到UI以及逻辑代码。 解决这个问题需要你理一下你项目中用到了哪些第三方so库,特别关注plugin,然后可以通过修改android目录下的ndk打包模式来进行调整。 修改的位置如下图: Android gradle 配置修改 有两种情况 如果你只打算适配arm架构,那么就修改为只打包armeabi-v7即可,你需要保证所有的so库,都有这个架构的so文件。 这里有一个坑,flutter现在打包默认不支持将libflutter.so以及libapp.so打到armeabi下,如果你想向上兼容,只对armeabi做适配那是行不通,这里有个骚操作,那就是先生成armeabi-v7 的apk,解压后拿到这两个so库,手动复制到armeabi目录下,在进行只有armeabi架构的打包,就可以了,是有些麻烦,注意,目前如果使用这个插件,需要按照这个步骤操作。 其实也可以修改flutter gradle文件,让它可以将这两个so文件打包到armeabi目录下,不是很好搞。

如果你打算适配不同架构,核心就是要不把不同架构so库找全了,全部统一到对应so目录下,在进行打包。

如果还是有问题,有个排查技巧,拿到启动会崩溃的apk,丢到as里面,查看lib文件,可以看到哪些so文件出了问题,这样比较直观 不同架构so库分析 上图所示,armeabi有41MB,是因为我把tbs浏览器内核放到了armeabi文件夹下,打包的是全平台,所以其他三个下面没有这些so文件,所以如果运行在arm64,x86设备上,内核是会挂载失败的。

总结

总结一下心得: 首先这边博客还只是算是给出了解决思路,实际看起来有些杂乱,杂乱的原因是目前我这个方案肯定不是最优解,需要后续完善,这里做一下记录,如果能吸引到牛人来一起探讨那更好了,我下一步的思路就是继续尝试修改flutter gradle,让flutter支持打包armeabi架构的apk,因为时间不是很多,之前只是简单试过没有成功。如果哪位有思路欢迎交流。

近期的一些思考 对于技术,每一个点,往细了深究都会牵扯到好多东西,需要静下心来去研究,试错,尽可能的使点连成片。以这篇文章来讲,我还有好多地方做的不过好,需要后续改进。 对于项目,不同业务情况不同的分析方式,面对不同Bug也要有不同的解决思路,具体问题具体分析,不要局限于一小块,已万变应对不变。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有