主要解決2個問題:
1.如何生成系統對應的簽名文件
2.解決 internal API 和 hidden API使用編譯報錯
首先生成簽名文件:
1.在github上下載工具 keytool-importkeypair,具體git地址如下:
https://github.com/getfatday/keytool-importkeypair
2.准備證書文件
platform.pk8 、platform.x509.pem
文件路徑:Android/build/target/product/security
3.將下載后的keytool-importkeypair文件及證書文件platform.pk8和platform.x509.pem文件放在同一個目錄下
4.使用Notepad打開keytool-importkeypair文件,鼠標右鍵點擊右下角,設置文件換行格式為Unix,具體如下
5.執行命令sh keytool-importkeypair -k ./platform.keystore -p android -pk8 platform.pk8 -cert platform.x509.pem -alias platform
6.AndroidManifest.xml中添加共享系統進程屬性,一般為android:sharedUserId="android.uid.system"
7.AndroidStudio添加生成的platform.keystore文件,可拷貝platform.keystore文件到工程根目錄下,如下圖所示。
8.修改Build Types,選擇release,因為我們之前打包就是選擇的release,需要保持一致。
9.因為系統app開發可能涉及到internal API和 hidden API的使用,不做處理會出現編譯錯誤,比如android.os.SystemProperties、ServiceManager.AddService,還需進行一些編譯配置,具體過程如下:找到Android源碼環境生成的android.jar文件,具體位置為out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar,可修改一下jar包名字為framework.jar,根據實際需要不修改也行,修改可讀性更好,拷貝該framework.jar包到工程app/libs/目錄下
10.設置framework.jar的編譯優先級,在工程根目錄添加build.gradle添加以下代碼:
project('app') { // app是你工程的名字,配置只對當前工程有效
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
// 注意修改 jar 包的路徑
// Xbootclasspath/p:是 Java 編譯的尋址優先設置,先找缺省路徑還是全路徑
options.compilerArgs.add('-Xbootclasspath/p:app/libs/framework.jar')
}
}
gradle.buildFinished {
pushDownSDK(".idea/modules/app/app.iml");
}
}
def pushDownSDK(iml) {
def imlFile = file(iml)
try {
def parsedXml = (new XmlParser()).parse(imlFile)
def jdkIndexOf = parsedXml.component[1].orderEntry.findIndexOf { it.'@type' == 'jdk' }
if (jdkIndexOf <= 1) {
def jdkNode =parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
parsedXml.component[1].remove(jdkNode)
new Node(parsedXml.component[1], 'orderEntry',['type': 'jdk', 'jdkName': 'Android API 28 Platform', 'jdkType': 'Android SDK'])
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(parsedXml)
imlFile.text = writer.toString()
println "Push File: $iml jdk priority ok"
groovy.xml.XmlUtil.serialize(parsedXml,new FileOutputStream(imlFile))
}
} catch (Exception e) {
// do nothing
}
}
11.run