• 尊敬的各位用户,柚坛社区APP延迟发布,详情点击点击查看

教程 使用Patchrom工具为自己的手机适配MIUI

  • 回复 5
  • 查看 1K
文章部分文本摘录自https://blog.csdn.net/kamidox/article/details/41777361
侵删.

MIUI官方已经停止为Patchrom工具更新了,相关代码也滞留在了MIUI8时代,而且并不支持Android6.0以上的底包,所以这个工具对于现在的新手机已经没有任何用处。
近几年的新手机就绕路吧。

什么是Patchrom?
Patchrom实际上是通过Smali Injection技术将第三方ROM的代码注入原生系统的Framework,将原生系统的ROM变成该ROM的一种适配方式;

Smail Injection技术指的是通过Android的反编译技术,将需要注入的Smali代码注入原有代码当中,使其拥有修改过的API和功能的技术。

拥有跨芯片平台,稳定性好,维护成本低,提供OTA服务(现在是不行了哦)的优点。

如何使用Patchrom工具适配MIUI?
目前为止的MIUI patchrom 代码
基于android 4.4.4的MIUI7是miui-7
基于android 4.4.4的MIUI6是miui-6
基于android 4.4.4的MIUI5是kitkat
基于androdd 6.0.1的MIUI8是marshmallow
还有jellybean42,jellybean42-mtk,jellybean,ics,gingerbread这些远古版本,就不进行介绍了。

“工欲善其事,必先利其器。”有个趁手的操作系统才能方便接下来的操作。
我们日常使用的Windows肯定是不行的,此教程上的所有操作都是在Linux平台上完成的。
Linux发行版有众多发行版,我比较喜欢Deepin,应用商店里面QQ,微信之类的日常软件基本都有。
当然你也可以使用Ubuntu,用的人多,网上的教程基本都是在Ubuntu上的,Ubuntu也可以装QQ,微信之类的软件,就是安装起来有些费劲,没有Deepin方便。
接下来的操作都是在Deepin中完成,在Ubuntu上的操作也大同小异。

第一步:安装JDK
安装JDK这个就不在这里教了,网上教程一大把,而且Deepin系统自带SDK,直接过就行

第二步:创建工作目录
在桌面右键打开终端
使用mkdir -p ~/binmkdir -p ~/patchrom命令创建文件夹在主文件夹内
输入:curl http://php.webtutor.pl/en/wp-content/uploads/2011/09/repo > ~/bin/repo 下载repo工具
下载完repo工具输入chmod a+x ~/bin/repo命令即可配置repo工具

输入cd patchrom进入patchrom文件夹后使用repo init -u git://github.com/MiCode/patchrom.git -b miui-7命令下载miui-7代码
下载MIUI6的代码就使用repo init -u git://github.com/MiCode/patchrom.git -b miui-6下载
如果下载别的代码把命令中的miui-7替换就行了,在上面都已经写过每个版本对应的字符串。

如果无法下载就用文件管理器进入patchrom文件夹,注意!不是用终端进入!
按Ctrl+H显示隐藏文件,看到有一个叫.repo的文件夹,进入.repo看到有一个叫manifest.xml的文件,用文本编辑器打开
将其中的fetch=".." />改为fetch="git://github.com" />
想重新下载就使用cd patchrom命令进入patchrom文件夹,在文件夹内使用repo sync命令再次下载代码

第三步:插桩反编译
使用cd patchrom命令进入patchrom文件夹
使用. build/envsetup.sh命令
然后新建机型目录mkdir <机型名称>
然后进入你新建的机型目录cd <机型名称>
连接手机使用adb reboot recovery命令进入recovery(注意!必须是第三方REC)
在recovery里挂载你的手机分区
接下来运行如下命令来拉取vendor:../tools/releasetools/ota_target_from_phone -r
从你下载的源码目录你找到其他机型的makefile文件修改好替换到你自己的机型文件夹里
下面的 makefile 可以作为模板,里面有详细的注释说明每个字段的含义。

#
# Makefile for <机型名称>
#

# 指定我们要移植的手机的底包,就是上一步骤里从recovery拉取的底包,默认名stockrom.zip
local-zip-file := stockrom.zip

# 编译我们移植好的 MIUI ROM 时的输出文件名
local-out-zip-file := 想叫啥就叫啥.zip

# 制作升级差异包时所需要的上一个版本的 ota 包目录,我们暂时还用不着
local-previous-target-dir := ~/work/ota_base/<机型名称>

# All apps from original ZIP, but has smali files chanded
local-modified-apps :=

local-modified-jars :=

# 哪些 MIUI 模块不包含在最终生成的 MIUI ROM 里。这里我们默认包含所有的 MIUI 模块。
local-miui-removed-apps :=

# 我们在移植过程中,使用了 MIUI 的 Phone 模块,但对 MIUI 的这个模块进行反编译并修改了部分 smali 代码使其功能正常。
# 针对 miui-6 这个分支,所有的 MIUI 模块定义在 patchrom/build/kitkat.mk 文件里。
local-miui-modified-apps := Phone

# 这个就是你手机的分辨率,根据自己的机型调整。
local-density := XHDPI

include phoneapps.mk

# To include the local targets before and after zip the final ZIP file,
# and the local-targets should:
# (1) be defined after including porting.mk if using any global variable(see porting.mk)
# (2) the name should be leaded with local- to prevent any conflict with global targets
local-pre-zip := local-pre-zip-misc
local-after-zip:= local-put-to-phone

# The local targets after the zip file is generated, could include 'zip2sd' to
# deliver the zip file to phone, or to customize other actions

include $(PORT_BUILD)/porting.mk

# To define any local-target
updater := $(ZIP_DIR)/META-INF/com/google/android/updater-script
pre_install_data_packages := $(TMP_DIR)/pre_install_apk_pkgname.txt
local-pre-zip-misc:
rm -rf $(pre_install_data_packages)
for apk in $(ZIP_DIR)/data/media/preinstall_apps/*.apk; do\
$(AAPT) d --values resources $$apk | grep 'id=127 packageCount' | sed -e "s/^.*name=//" >> $(pre_install_data_packages);\
done
more $(pre_install_data_packages) | wc -l > $(ZIP_DIR)/system/etc/enforcecopyinglibpackages.txt
more $(pre_install_data_packages) >> $(ZIP_DIR)/system/etc/enforcecopyinglibpackages.txt

out/framework2.jar : out/framework.jar

%.phone : out/%.jar
@echo push -- to --- phone
adb remount
adb push $< /system/framework
adb shell chmod 644 /system/framework/$*.jar

%.sign-plat : out/%
java -jar $(TOOL_DIR)/signapk.jar $(PORT_ROOT)/build/security/platform.x509.pem $(PORT_ROOT)/build/security/platform.pk8 $< $<.signed
@echo push -- to --- phone
adb remount
adb push $<.signed /system/app/$*
adb shell chmod 644 /system/app/$*

在mkefile准备完毕后,便可以开始构建新的机型工程。以下命令会自动反编译:make workspace

输入上面的命令后使用make firstpatch命令即可自动插桩

第四步:解决冲突
这一步需要Smali语法的基础,不会的可以去百度一下,网上挺多讲解Smali语法的文章
这个命令尝试自动合并 smali 文件。如果无法合并,会在 reject 目录下生成有冲突的文件。所以,运行这个命令后,我们只需要合并 reject 目录下的有冲突的文件即可完成 MIUI ROM 的移植工作。

这个命令在 patchrom/<机型名称>/temp 目录下生成的文件树如下:

├── dst_smali_orig # 这个是底包 stockrom.zip 里反编译出来的系统 smali 文件
│ ├── android.policy.jar.out
│ ├── framework.jar.out
│ ├── mediatek-framework.jar.out
│ ├── secondary-framework.jar.out
│ └── services.jar.out
├── dst_smali_patched # 这个是程序自动合并的目标 smali 文件
│ ├── android.policy.jar.out
│ ├── framework.jar.out
│ ├── mediatek-framework.jar.out
│ ├── secondary-framework.jar.out
│ └── services.jar.out
├── new_smali # 这个是 MIUI ROM 里反编译出来的系统 smali 文件
│ ├── android.policy.jar.out
│ ├── framework.jar.out
│ ├── mediatek-framework.jar.out
│ ├── secondary-framework.jar.out
│ └── services.jar.out
├── old_smali # 这个是 AOSP 里反编译出来的系统 smali 文件
│ ├── android.policy.jar.out
│ ├── framework.jar.out
│ ├── mediatek-framework.jar.out
│ ├── secondary-framework.jar.out
│ └── services.jar.out
└── reject # 这个是由于冲突程序无法自动合并,需要手动合并的 smali 文件
├── android.policy.jar.out
├── framework.jar.out
├── secondary-framework.jar.out
└── services.jar.out
可以阅读 patchrom/build 和 patchrom/tools 两个目录下的 makefile 和 shell 源码来理解 make firstpatch 过程到底做了什么事情。

手动合并 smali 代码的流程是这样的:

①用文本编辑器逐个打开 reject 目录下的所有文件,找出冲突的代码块
②用 BeyondCompare/Meld 工具去比较 old_smali 和 new_smali,找出冲突代码块的位置
③通过比较阅读 smali 文件理解 MIUI 在 AOSP 的基础修改了什么逻辑
④用 BeyondCompare/Meld 工具去比较 dst_smali_orig 和 dst_smali_patched,找出冲突代码块的位置
⑤根据步骤③的逻辑修改,把这个修改合并进 dst_smali_patched 目录

冲突解决完就可以在你的<机型名称>目录下使用make fullota命令打包了
如果你人品足够好,那么可能一步就生成了。但基本上没有这么好的运气。过程中会有 smali 错误。需要根据提示去做适当的修改。编译通过后,就可以把 想叫啥就叫啥.zip 文件通过 recovery 方式升级到手机看移植后的效果。
 

热门资源