前言
今天刚刷上Apatch,发现其没有提供Zygisk,又去酷安搜了一搜,似乎有人反应刷Lsposed不起作用,大致了解了一下,并查了些资料。下面我开始猜测以及进行理论。
说是从软件工程出发,但是实际上我并不算一个好学生,更无法代表软件工程,这或许很标题党,但是我确实想以这个名称命名。
一言蔽之,Apatch和KernelSu之类的本来就只是Root解决方案,只不过Magisk太流行了,如果不对magisk模块进行一些兼容,没人会去使用KernelSu之类的软件。事实上直到如今,Root管理器中占有率最高的依然是面具。
铺垫
在此之前,我们可以说一说接口和继承这个老生常谈的问题。当然,我无法代表软件工程,所有的见解只是个人思考和猜测,甚至很可能出现大量错误,权当我胡说,当个笑话看看就好。
我说说我对接口和继承的简单理解。
继承:"普通人类和机器人都是人"。
接口:"小米手机和OPPO手机都是手机"。
这个例子也许不是很好,我其实在尽力地使这篇文章变得有趣起来,我想表达的是,继承通常是允许扩展的,允许添加新功能的,而接口我们通常不允许扩展,该有什么功能就应该实现什么功能。至于怎么实现和如何实现,我不管你。
从代码的编写上来说,继承通常是允许新的方法出现的,他允许子类(派生类)拥有其他子类未拥有的方法,大家可以有非常多的不同点。
而接口不同,我们通常实现接口都是只实现接口所约定的方法,而不去写新的方法,除非我们让这个类去同时实现另一个接口。或者换句话来说,接口不关心其他的方法。
对于不熟悉代码的同学,我们可以简单的把接口理解为功能,而父类子类简单理解为父与子。
事实上接口完全允许其他的方法存在,但是大家都不太会去为一个实现了接口的类实现接口之外的方法。原因也很简单,因为
单一职责原则
。
为什么
说到这里,我的用意就很明显了,各个root管理器更像是继承了某个父类的不同子类,而非实现接口。
其实既不是继承也不是接口,因为他们的开发者本就不同,根本就没有进行约定的义务,他们爱写什么写什么,你管不着。
早期,我们只希望拥有root管理器,SuperSu就是这个需求的一种实现。
后来,supersu不更新了,不支持新的系统,于是magisk出现了。
很遗憾我并不清楚magisk的完整历史,但是假设magisk初期就提供了模块化支持。(至少我接触的时候就已经有模块了)
模块是个好东西,magisk出现就占据了大量市场,大家都对magisk赞不绝口。
此时我们再假设,假如历史长河中,出现了一款名为UltraSu
(neta SuperSu)的软件,他提供插件化支持,就像浏览器插件那样。由于二者出现时间相近,而当时大家的需求是root,从来没想过模块的问题。
那么magisk模块和UltraSu互不兼容就是可以预想的事情了,到这里我的核心思想已经表现出来了。你自然可以丢下这篇文章不管。
不过我可要继续说下去了。
大家都知道,根本没有UltraSu这个东西,至少有很长一段时间,大家都在使用magisk而不是什么别的管理器。
magisk也衍生出了别的版本,广为人知的就是Alpha和Delta(现在叫kitsume)。
vvb2060https://github.com/vvb2060
Alpha的作者自不必多说,我认识面具的时候隐隐约约就知道他是面具的维护者之一,而且他还是Lsposed的维护者。
那么兼容性好是可以预见的。
delta我其实不太清楚,无论如何,兼容性应该也不会比Alpha好。
如果再说回前面的继承和接口,这俩就类似继承,他们从magisk分支出来,提供了新的功能。
扯远了,让我们再拉回时间线,现在magisk火的一塌糊涂,在那之前,还有一款软件也很火爆。
xposed
我不太清楚xposed是什么时候流行起来的(远古级xp模块上帝模式
,他在这个时期非常受欢迎,哪怕是edxp时期),但是这对本文没什么影响。我们假设xposed和magisk是近乎同时流行的。(印象中xposed更早)
这时,magisk和xposed还是互不相干的两个项目。发展了一段时间,大家的需求变成了root以及xposed模块,由于magisk的流行,大家也离不开magisk模块了。
这时候大家的需求如下:
0. 不修改system(最早由面具实现了)
- root(SuperSu时期就已经实现,更早的不考虑)
- xposed模块
- magisk模块
- 隐藏root等一系列环境?
于是,不知何时,EdXposed出现了。
项目地址
https://github.com/ElderDrivers/EdXposed
他的出现主要解决的问题就是,如何在不修改系统的情况下,使用xposed框架
。至于系统兼容性是顺带解决的,EdXposed通过刷入Ruri模块(提供运行环境),实现了Xposed框架实现的功能,与此同时,由于模块不修改系统,需求完美地解决了。
其实这时候我才初步接触Xposed。至少当我认识Edxp的时候,他已经是使用模块的方式安装了,早期xposed是用installer安装的,和magisk没有什么交集。
Edxp同样非常流行,可以说是一统江湖,直接替代了xposed。
印象中,SuperSu+Xposed -> Magisk + Edxposed。
而后某一天,LSPosed出现了,他的出现让人意外,因为他的出现不是由市场催生的,而是由社区呼吁而成。(还是仅为猜测)
EdXposed和原来的Xposed都存在一个问题,无论目标应用是否正在运行,xposed的环境都会注入,这会导致性能问题,因此,Lsposed实现了作用域功能,使得模块仅对某些应用生效。
我合理地进行猜测,早期Lsposed使用Ruri提供环境注入。(官方术语为zygote)
而后期,Magisk项目提供了Zygisk(zygote注入的一种实现,Zygisk的目的是隐藏Root环境,也就是MagiskHide),于是Lsposed也去适配Zygisk。
下图为Lsposed在github的更新日志,
再后来,Magisk的作者topjohnwu https://github.com/topjohnwu
他被谷歌收编,虽然能够继续开发Magisk,但是似乎不被允许更新Zygisk。
相近地,KernelSu等框架横空出世,他们没有Zygisk之类的注入环境,如果用户需要使用Lsp等xp框架,KernelSu没有办法。
这也是Zygisk Next https://github.com/Dr-TSNG/ZygiskNext 出现的原因
作者
https://github.com/Dr-TSNG
(他曾参与Lsposed的开发)
下面这张图是开了网页翻译(考虑到文章的可读性)
他的出现间接地帮助了所有的Root管理器(除了死去的SuperSu),因为早期的Ruri https://github.com/RikkaApps/Riru 已经不更新了。
大规模弃更事件
而且,由于一些众所周知的令人气愤而又无奈的原因,Lsposed团队的多个项目也不再更新(归档了)。
也许有人不明白不再更新的意义是什么。我说一个最浅显的表现,
这些项目将很有可能不能在较新的机型上使用,比如如今的Android15机型
。
可以说这个事件造成了非常坏的影响,祸不单行,小米很快更新了解锁的条件,具体是什么大家都清楚。
时间先后我记不得了,我只记得这两件事发生的时间很近,不超过一年。
我知道有很多人会说,哪怕没有这些开发者,也会有Root的实现。没有SuperSu,也会出现UltraSu;没有Ruri,也会有Zygisk。你看Zygisk Next不是出现了吗。
那我确实没法反对,根据客观规律,有需求就有市场,上面这段话是对的。但是这种话是最不该对Lsposed团队说的,因为Lsposed是被社区推动的,可以说近乎是浪漫的产物;同时期下EdXposed依然在被使用,他们完全可以不开发这个东西。
可以看到,EdXposed并没有归档,只是不再更新了
为什么不更新呢?因为显而易见,别人的项目Lsposed更好,维护EdXposed没有意义了。几个EdXposed的维护者全跑去更新Lsposed了。
假如EdXposed还在维护,你会去用Lsposed吗?
题外话
如果你细心观察,你会发现,搞root框架和相关的环境的维护者,来回就那么几个。
如果你说搞这些项目是为了给自己镀金。
人家招聘的问你会什么,你说你参与开发了Magisk,我听着都想笑。
所有手机厂商都是不鼓励你root的,因为用户的权利和厂商的权利往往站在对立面。
我开发一个软件,如果我想让他按照我预想中的执行,最好的办法就是用户什么都干不了,用户的权限越大我的风险就越高,我不让解锁了。维护的版本越多bug就越多,那我强制更新不就好了。(很多软件的做法)
因此显然,鼓捣这些东西去工作时没什么用的。而且说难听点,项目维护很大程度上都是体力活,费时间而没有什么技术含量。
回到正题
我们再拉回时间线。现在magisk依然如火如荼,Lsp依然如日中天(因为Android15并未普及),这两者的出现都是一统江湖的,没什么竞争对手。(在当时)
而现在,出现了KernelSu和Apatch这两个竞争者,我们可以重新梳理一下当前用户的需求。
Root
除了SuperSu,这几款软件都实现了Magisk模块
- SuperSu(不再更新)
- Magisk
https://github.com/topjohnwu/Magisk - KernelSu(作者是太极和虚拟框架的作者weishu)
https://github.com/tiann/KernelSU - Apatch
https://github.com/bmax121/APatch
提供Zygote注入环境
现在Zygote注入实现只剩下Zygisk方式了,不出意外以后不会再有Ruri
- Magisk官方提供的Zygisk以及MagiskHide(已经过时)
- Ruri(EdXp时期,以及Lsp的前期)
https://github.com/RikkaApps/Riru
叫琉璃的人太多,猜不出来是谁,或许只是一个泛称 - Zygisk Next(唯一幸存者)
https://github.com/Dr-TSNG/ZygiskNext
隐藏Root(隐藏注入器)
我不太清楚Zygisk什么时候出现的。
KernelSu和Apatch都实现了隐藏su(也就是Root),但是如果你使用了Zygisk(Zygote注入的实现),你还需要隐藏Zygisk。
- Zygisk环境下,使用MagiskHide(自带,停止更新)
- Shamiko(MagiskHide的一种实现?停止更新)
Shamiko借用的依然是官方Magisk的
配置排除列表
,需要Zygisk环境,默认是黑名单模式,也就是对列表中的应用隐藏Root。
Shamiko应该是夏美子,街角魔族的主角。(没人比我更懂二次元.jpg)
- MagiskHide模块?(我没用过)
- 其他的,有很多,但我不太了解......
Xposed模块实现/管理器
除了早期的Xposed Installer,这些必须有Zygote注入环境
- Xposed Installer和Manager(过时)
- Edxposed(过时)
https://github.com/ElderDrivers/EdXposed - Lsposed(停止维护)
https://github.com/LSPosed - Lsposed Mod(下一代)
https://github.com/mywalkb/LSPosed_mod
回到正题
虽然很简单,但是我讲了一大堆(而且很乱)。
兼容性最强的自然是各个实现只实现它本该实现的功能。
但是我们先说说兼容性最差的情况,假设某个zip直接包含了全部的环境(以上的全部需求),是不是很强很方便?但是,首先没有人有这么大的精力去整合所有项目,其次,如果集成在一起,你如何知道哪个部分出了问题?
我们再说兼容性最强的方案,假设每个功能都以单独模块出现,那其实也很糟糕,假设Magisk分成了多个部分,比如把Root管理和模块管理分离,再把排除应用列表分离。那么你从前卡刷面具这一步,就会复杂成刷好几个模块,安装好几个应用。
其次,假设你只实现了Root管理,我凭什么用你Magisk?一个应用只有解决了某个需求才会有人去用,才有意义,假设许多应用都只干同一件事,那么想要获得用户只能靠宣发了。而开源应用和宣发基本上沾不上边,因为宣发是要钱的。搞开源已经很费钱了(时间也是钱),哪来的钱搞宣发。
还有一个原因,Magisk本身也在积极地更新,假如某个模块使用了Magisk的新功能,自然会存在不兼容Apatch和KernelSu。(而且Apatch之类的和Magisk的环境也不同,而之前的模块都是以Magisk环境为准的)
而Apatch和KernelSu如果花时间去兼容Magisk,完全是不务正业,而且吃力不讨好,因为旧的写法通常比新的多,为了5%的模块去花50%的时间并不值得。
所以这个问题无解,除非Magisk模块功能被单独实现,但是这就更不可能了,因为Magisk的核心功能就是模块,他是用模块来解决问题的,倒不如说Root才是顺带的。
原谅我长篇大论一大堆说了这么些浅显的道理。