Android Stdio 引入自定义framework.jar 自定义framework-res.apk 中 attr

来源:互联网 发布:淘宝买东西优惠软件 编辑:程序博客网 时间:2024/05/17 03:28

如果开发一些依赖framework中隐藏方法的应用的话, 如果一直用反射比较繁琐, 所以如果导入framework.jar, 编译的时候依赖framework, 打包的时候不打包, 这样开发就简单了许多, 而且效率也搞。


这个功能之前在eclipse中的实现网上有很多教程都介绍了, 现在都转到AS了, AS的优点太多了, 我转过来是因为要使用aar。


第一步把framework.jar当做一个普通的lib包导入AS, 教程太多了(记得选的Providered方式, 不打包到APK)


关键第二部: 至今网上没介绍:

原理是理解AS的编译依赖环境的配置, 这个文件保存在 app 下的 iml 文件(Project一个iml, 每个Model有自己的iml, 你需要修改具体app下的 iml)


<orderEntry type="library" exported="" scope="PROVIDED" name="framework" level="project" /><orderEntry type="sourceFolder" forTests="false" /><orderEntry type="jdk" jdkName="Android API 22 Platform (1)" jdkType="Android SDK" /><orderEntry type="library" exported="" name="appcompat-v7-21.0.3" level="project" />

把 framework的order提高到比SDK的等级高就可以了

更新:

上面其实解决的只是AS上编译器的依赖问题, 当真正使用Gradle打包的时候又会出现问题, Gradle使用的不是之前iml配置的依赖顺序 (PS: 之前成功是由于AS编译缓存给我造成的假象)。


最近研究了Ant打包的流程, 引入自定义 framework.jar

    <target name="-pre-compile" >        <echo message="JARPATH=${toString:project.target.class.path}"></echo>    <property name="framework.dir" value="${jar.libs.dir}/framework"></property>    <path id="framework.lib">        <pathelement location="${framework.dir}/framework.jar"></pathelement>        <path path="${toString:project.target.class.path}"></path>    </path>    <path id="project.target.class.path">        <path refid="framework.lib"></path>    </path>    <echo message="JARPATH=${toString:project.target.class.path}"></echo>    </target>

分析:  project.target.class.path 其实指向的是android.jar的位置, 只要把自定义的framework.jar 引入这里, 编译的时候会先查找自定义的framework.jar, 打包的时候也不会打包的 classes.dex 里面。


Android Studio 的方式: 

通过艰难努力, 终于搞定了这个问题, 而且是十分优美的方式搞定的。


1: AndroidStudio IDE 的编译无错误提示

这里推荐在 Iml 文件中自定义: 
<orderEntry type="jdk" jdkName="Android API 22 Platform-aosp" jdkType="Android SDK" />

如何自定义Android API 22 Platform-aosp, 首先把这个名字改错, 然后编译, 根据提示进入到SDK的编辑界面:


这里先删除 android.jar 然后再加入 framework.jar 和  android.jar

这样就确保IDE编译无错误。

2: Gradle的编译出APK


这里就是重头戏了, Gradle的编译脚本是定义在 build.gradle 中的。

对于三方普通的 jar 包的处理, 比较简单:
dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    compile 'com.android.support:support-v4:22.1.1'    compile 'com.github.lecho:hellocharts-library:1.5.5@aar'    compile 'com.avast:android-styled-dialogs:2.2.0'}
但是这里无法配置我们需要的jar包(优先级比android.jar高, 而且不要打包到 dex 文件中)
我们可以配置:
allprojects {    repositories {        jcenter()    }    gradle.projectsEvaluated {        tasks.withType(JavaCompile) {            options.compilerArgs.add('-Xbootclasspath/p:libs\\framework.jar')        }    }}
解释一下, 这是在最外层的 build.gradle 里面配置的, 目的是应用到所有的模块。
在进行 javac 编译的时候, 添加一个参数。 其实和上面Ant编译的命令是一样的, 都是在 bootclasspath 中引入自己的 jar 包。
测试真实有效(PS 清除了缓存, 没有再次被欺骗)

3: 引入framework-res.apk 中自定义的属性

如果看到这里, 我就告诉你跟build tools的版本有关, 高版本的会过滤掉你自定义的attr, 你需要使用低版本(推荐 19.1.0)

这个是折磨了很久的编译问题, 至今未看到网上有相关的介绍, 如果还有疑问可以发邮件: eva_59421@163.com  

1 0