Android工程导入系统Jar包
背景
有时候在开发APK时需要一些特殊权限的API或者hide的方法,比如打开WIFI热点等,
可以调用通过系统源码编译出来的系统Jar包来解决
导入系统Jar包
将
framework_all.jar
添加进工程,一般为app/libs
目录
右击选择Add As Library
,或在Project Structure
中添加导入相关依赖,也可直接修改文件。根目录下的
build.gradle
中设置allprojects { repositories { jcenter() google() } gradle.projectsEvaluated { tasks.withType(JavaCompile) { options.compilerArgs.add('-Xbootclasspath/p:app/libs/framework_all.jar') } } }
module下的build.gradle添加设置来更改引用库的优先级,优先引用自己添加的jar
preBuild { doLast { def imlFile = file(project.name + ".iml") println 'Change ' + project.name + '.iml order' try { def parsedXml = (new XmlParser()).parse(imlFile) def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' } parsedXml.component[1].remove(jdkNode) def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform" new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK']) groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile)) } catch (FileNotFoundException e) { // nop, iml not found } } }
编译gradle,打开app.iml发现顺序果然换过来了
在Module下的
build.gradle
下的android->defaultConfig
里面添加multiDexEnabled = true
注意
gradle
版本
删除jar包的某些class
将jar
重命名为zip
,即xxx.jar->xxx.zip
解压
删除需要删除的文件
重新打包jar(需安装java环境):
进入文件夹,
jar cvf xxx.jar .
问题
对findViewById的引用不明确
错误: 对findViewById的引用不明确
Activity 中的方法 findViewById(int) 和 AppCompatActivity 中的方法 findViewById(int) 都匹配,其中, T是类型变量
常见主流解决:
1.网上最常见的办法是统一各个module的compileSdkVersion,向高版本看齐
2.Android Studio->File-Invalidate Caches / Restart
3.升级AS和Gradle版本
AS工程的build.gradle设置了framework.jar包优先编译,去掉设置优先顺序
我的工程引入了framework.jar,习惯性按照以前的方式设置了优先顺序。神坑,最近因为调试需要,将Activity改为继承自androidx.appcompat.app.AppCompatActivity结果意外暴露出问题,之前一直继承自android.app.Activity。
//以下代码的作用: 让framework.jar优先参与编译
//副作用: 在使用AppCompatActivity的时候findViewById无法正常使用
//错误: 对findViewById的引用不明确,Activity 中的方法 findViewById(int) 和 AppCompatActivity 中的方法 <T>findViewById(int) 都匹配
//其中, T是类型变量:
//屏蔽之后运行正常
//如果必须设置gradle.projectsEvaluated,那么在实例化View的时候,把findViewById改为getDelegate().findViewById,这样就可以避免歧义
// gradle.projectsEvaluated {
// tasks.withType(JavaCompile) {
// options.compilerArgs.add('-Xbootclasspath/p:readme/framework.jar')
// }
// }
参考
https://www.jianshu.com/p/54ff6389ddef
https://blog.csdn.net/u010725171/article/details/106357735/