【KBrowser】基于 Kiwi/chromium 制作全新外壳,将 chromium 代码当作 webview 使用,实现可控核替换

别人套壳我套核,换壳又是新界面

  • 编译参考
    • Kiwi 编译宗旨
    • Kiwi classic 无法正常编译
    • 别人提供的编译方法
    • 云编译后,二次开发的方法
  • UI 定制思路
    • 全新的界面设计,不再是差不多的“回声”
    • 独特的定制方法,有助于创造力的迸发
    • 合理的接口,有助于效率的提高
  • 主要坑点
  • 开源
    • 基石 Foundation I
    • 第二基石 Foundation II
  • 插件化计划
  • Play 应用市场 上架计划

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 编译宗旨

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 classic 无法正常编译

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

UI 定制思路

全新的界面设计,不再是差不多的“回声”

我希望对kiwi/chromium进行二次开发,但是不想用它的界面体系,而是将之当作 webview,这样,只需几步替换工作,就能实现“换核”,结合kiwi内核与我写的外壳逻辑 ——

  1. 全新的界面设计 ,将会带来全新的浏览体验,而不是 chromium 或 kiwi 的单调“回声”;
  2. 界面上同时参考了 via 浏览器与 opera mini 浏览器。
  3. 标签页支持viewpager横向预览图、垂直 listview 列表两种模式。
  4. 升级 kiwi 代码库至 androidx
  5. 支持 标签页缩略图,或列表模式
  6. 支持 标签页搜索
  7. 支持 在主界面地址栏切换搜索引擎
  8. 支持 在主界面定制搜索引擎,添加、编辑、排序

独特的定制方法,有助于创造力的迸发

chromium java 层七绕八绕,很多delegate,但是该抽离的代码却是不抽离,比如 Activity 必须 extend ChromeActivity。

我的思路是,逐步简化 ChromeActivity,实现 ChromeActivityDelegate,将 Activity 生命周期与 chromium 内核加载的代码分离,这样,就能在任意 Activity 上下文创建 kiwi webview 了!

实现无限拓展、无限自由。

合理的接口,有助于效率的提高

我的思路是,拓展一个 webview 作为 wrapper,调用真正的 kiwi delegate,操作 tab 相应的方法,许多接口几乎一致:

  • loadUrl
  • goBack
  • evaluateJavaScript
  • addJavascriptInterface
  • shouldOverrideUrlLoading,关键词 newpage、create webcontents

其中 evaluateJavaScript、addJavascriptInterface 等方法,反编译出来的代码里没有, src 仓库有,其实就是安卓系统 webview 的源代码,复制粘贴即可。

也有不兼容的:

  • shouldInterceptRequest,未找到
  • onScrollChangeListener,未找到
  • saveState,未找到
  • onScaleChangeListener,虽然没有监听器,但可以直接在java层读取缩放值的,关键词 page scale

此外,有些接口无法直接拓展,需要另外自定义 interface 。

最终,实现 应用层 与 底层webview 分离,编译应用层的分支时,只需复制应用层代码,基本不变,实现高性能换核。

主要坑点

  1. kiwi 并不支持 所有 webview 接口,不可兼得,所以当作备选的甜点,兼容旧设备。 新设备最好还是直接用系统webview,插件也不必支持,用户脚本足够,而且性能应该更好。不要为 chrome 开发新插件 不要为 chrome 开发新插件 不要为 chrome 开发新插件 ,chrome 又不发钱!
  2. 虽然套核也勉强能支持 chrome 插件,但tab相关、历史记录、收藏夹等相关的api断开,太绕了,java层各种 model、observer、impl、delegate、callbynative 不知怎么接上。
  3. java 层有许多监听器,会在窗口级别监听所有操作,监听activity生命周期,还反射。关键词 WindowCallbackProxy、applicationstatus、invoke
  4. 升级 kiwi 代码库至 androidx,一些不兼容的,主要是 play gms 、fragment 中的代码,只能删除或throw。
  5. 多进程模式不能在 kiwi 内核 初始化完成之前 新建原生webview,否则native会崩溃
  6. debug 模式的java层有 strictmode、assert等,其中 strictmode 会在启动时显示屏幕周围红色边框。
  7. 代码太多,编译较慢

开源

基石 Foundation I

可编译打包 ChromePublic.apk ,云编译、反编译、patch源代码后获得,是二次开发的基石

TODO,稍后放gihtub

第二基石 Foundation II

不含浏览器的业务逻辑,所以不能直接编译,仅作参考。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的效果,但还有许多资源加载的问题,需要修复。

Play 应用市场 上架计划

下次再说

你可能感兴趣的:(编译奇兵,安卓,android,webview,chrome)