Kiwi 是安卓上最好的 chromium 编译版本,而且开源、支持chrome扩展、支持黑暗模式。kiwi 运行流畅,尤其是 classic 版本,基于 chrome 77 ,只有 50 MB。最新的 kiwi next 虽然基于最新内核,但是体积也增大到了 180 MB。
Kiwi 的优势是向下兼容旧的安卓设备、可安装扩展。
比如 系统黑暗模式要 安卓 10 以上才支持。而 Kiwi 实现的 黑暗模式 兼容 kitkat、安卓5、安卓6、安卓7、安卓8.
直接修改 Kiwi 是枯燥乏味的。因为 chromium java 层代码非常绕,很多抽象,但是该抽离、该分化的代码,却是一坨一坨,垒起护城,外人难改,即使修改,也是套壳,变化甚少。
本文提供一种 chromium 浏览器二次开发的新思路,比较新颖,可以简单地将 Kiwi 的代码隔离,进而将 chromium 内核转化为 webview,从而使得界面定制没有限制。
Kiwi 基于云电脑编译,作者认为任何需要本机IDE的操作都是过于复杂而多余的。
转载原话如下:
The mindset behind this project is that you should be able to modify and create a modification of Kiwi Browser directly from within Kiwi Browser (without the need of a computer).
Keep it in mind, if you need a computer to do a change, it means it’s too complicated. Even rebasing should be doable from the GitHub user interface.
Servers are paid-for and sponsored by Geometry OU (the company behind Kiwi Browser), and additional computing hours for contributors are provided for free by Microsoft Azure via GitHub Actions.
Kiwi 最新版似乎也是基于 action,但体积太大,没啥兴趣。
Kiwi 经典版本的编译脚本已经失效,失效原因:github actions 已在今年早些时候废弃 ubuntu-18.04,而新版 ubuntu没有许多需要的依赖。
幸运的是,通过检索 github kiwi/src 的分支项目,我找到了两位开发者的薪火传递,让 kiwi/src 得以重新编译:
AoEiuV020 大神 :
kiwibrowser-build 的一部分,
kiwibrowser-ccache-arm64
加上这两个项目实现使用github actions跑编译kiwibrowser android apk,
两年前是能跑的, 现在估计不大行,应该会有一些依赖存在问题,
wankaiming 神秘大侠:
新的编译脚本:kiwibrowser-build
fork并引用了编译缓存 ccache:kiwibrowser-ccache-arm64
并修改了 java 层源代码:kiwibrowser-src
c++ 代码是怎么编译的不是很明白?kiwibrowser-build 编译只需一小时,是用了 ccache 仓库的编译缓存。
每次编译都需要一小时,也不知kiwi作者怎么坚持下来的,是不是藏私了?!
其实二次编译是最便捷的 —— 导入 android studio,修改 java代码、res 图像资源后,一键运行。
我的方法比较新颖,是在云编译时,开启 is_java_debug,这样 java 层就不会混淆。
云编译后,再用 jadx 反编译,导出 gradle 项目,导入 android studio。
但是还不能直接用,因为 jadx 其实是代码翻译,有时不准的。
所以需要从 github kiwi/src 下载 java 层的源代码,将之替换。
替换好源代码的状态如下:
todo
我希望对kiwi/chromium进行二次开发,但是不想用它的界面体系,而是将之当作 webview,这样,只需几步替换工作,就能实现“换核”,结合kiwi内核与我写的外壳逻辑 ——
chromium java 层七绕八绕,很多delegate,但是该抽离的代码却是不抽离,比如 Activity 必须 extend ChromeActivity。
我的思路是,逐步简化 ChromeActivity,实现 ChromeActivityDelegate,将 Activity 生命周期与 chromium 内核加载的代码分离,这样,就能在任意 Activity 上下文创建 kiwi webview 了!
实现无限拓展、无限自由。
我的思路是,拓展一个 webview 作为 wrapper,调用真正的 kiwi delegate,操作 tab 相应的方法,许多接口几乎一致:
其中 evaluateJavaScript、addJavascriptInterface 等方法,反编译出来的代码里没有, src 仓库有,其实就是安卓系统 webview 的源代码,复制粘贴即可。
也有不兼容的:
此外,有些接口无法直接拓展,需要另外自定义 interface 。
最终,实现 应用层 与 底层webview 分离,编译应用层的分支时,只需复制应用层代码,基本不变,实现高性能换核。
可编译打包 ChromePublic.apk ,云编译、反编译、patch源代码后获得,是二次开发的基石
TODO,稍后放gihtub
不含浏览器的业务逻辑,所以不能直接编译,仅作参考。kiwibrowser.webview 是我新建的包,
其中 PluginTest1 测试 delegate,包括 Delegate、ChromeActivityDelegate 与 AsyncInitializationActivityDelegate。
ChromeActivityDelegate 与 AsyncInitializationActivityDelegate 分别对应kiwi中的 ChromeActivity、AsyncInitializationActivity,他们调用 NativeInitializationController.startBackgroundTasks 加载内核,并创建 tab 视图。
Tab 的视图组成:包括在 CompositorViewHolder 下、ComositorView 里的 SurfaceView,以及 CompositorViewHolder 里的 ContentView,总体由 R.layout.main 创建。
旁边 PluginTest 是失败的测试,尝试不用delegate直接加载内核、创建视图。测试结果是页面加载后画面不显示,但是点击和长按有反应。
webview.java 是失败的多进程插件化测试,测试结果是内核加载了、视图创建了,几秒后 Timed out waiting for GPU channel。
KBrowserWebView 是 KBrowser 接口层,里面的 webview 是 kiwi delegate 的 wrapper。视图通过 getView 接口提供。
TODO,稍后放gihtub
单进程内核可以插件化,实现类似webview.apk的效果,但还有许多资源加载的问题,需要修复。
下次再说