ant build.xml 打包应三方jar注意的问题与混淆R的写法

老规矩我们还是来看看说在前面的话:首先我们得分清楚android在打包成apk的过程中要经过哪几个步骤:

Android编译的具体流程如下:


1)  ndk-build编译native代码生成so文件


2)  aapt命令根据res资源文件生成R.java


3)  aidl命令解析.aidl文件生成对应java文件


4)  javac命令编译java文件为class文件


5)  dx命令将编译好的class文件打包为dex文件


6)  aapt命令根据res资源文件生成resources.ap_资源索引文件


7)  apkbuilder将resources.ap_与dex打包成未签名apk文件


8)  jarsinger签名apk文件


9)  zipalign工具优化apk读取速度

这里我想重点说的是javac这个阶段和aapt打包成res文件混淆的问题。

这里我们看看假如我们的工程里面如果应用到了第三方的jar应该怎么写,我们首先需要把我们的jar包复制到我们的libs下面然后修改一下编译这里的脚本,假如这个外部工程还有自己的R文件和res资源我们在写脚本的时候需要注意这几个问题.

1:编译成R文件的时候记得一起打包这个外部依赖项目的R文件。

2:编译class文件的时候记得加入lib依赖

3:打包res文件的时候记得外部文件的res也要添加

4:如果项目中有混淆记得不要混淆外部依赖文件的R文件,不然找不到外部的R

这里我来举个例子吧,我这里例如我用到了,PullrefreshListview这个外部依赖工程,需要注意的是这几个步骤,我贴出脚本吧。先看看编译R文件的时候的脚本。

<!-- 为该项目资源生成R.java文件 -->
<target name="gen" depends="init">
<echo>从资源文件生成R.java ...</echo>
<exec executable="${aapt}" failοnerrοr="true">
<arg value="package" />
<arg value="--auto-add-overlay"></arg>
<arg value="-m" />
<arg value="-J" />
<arg value="${gen}" />
<arg value="-M" />
<arg value="AndroidManifest.xml" />
<arg value="-S" />
<arg value="res" />
<arg value="-S" />
<arg value="C:\Users\edsheng\Desktop\Android-PullToRefresh-master\library\res" />
<arg value="--extra-packages" /> 
<arg value="com.handmark.pulltorefresh.library"/>

<arg value="-I" />
<arg value="${androidjar}" />
</exec>
<echo>R.java文件生成成功</echo>
</target>

看到我红色的部分了吗?这些就是外部依赖工程的时候需要添加的脚本是把我们外部依赖的res文件拿去生成R,文件。

然后需要注意的第二部分,编译class文件记得加入jar的依赖,我们要把用到的jar先复制到lib里面,由于Pullrefreshlistview这个工程是个lib工程,我们直接拷贝lib到我们的主工程的libs文件目录下边然后看看javac编译class文件的脚本。

<target name="compile" depends="aidl">
<echo>开始编译.class文件...</echo>
<javac fork="true" executable="${javac}" encoding="${encoding}" debug="true" extdirs="" source="1.5" target="1.5" destdir="${classes}"  bootclasspath="${androidjar}">
            <src path="${src}" />
            <src path="${gen}" />
            <classpath>
                <fileset dir="${root}/libs">
                    <include name="*.jar" />
                </fileset>
                </classpath>

        </javac>
<echo>.class文件编译完成</echo>
</target>


也是要理解这个编译过程要找libs下面的所有jar,同理然后我们来看看混淆代码的时候要注意的东西,一个就是lib文件一个就是混淆的时候lib的资源R文件不要去混淆了,这里我也贴出自己的混淆的脚本。

<target name="obfuscate" depends="compile">


        <echo>对打包的结果进行混淆...</echo>
        <java jar="${proguard_home}/lib/proguard.jar" fork="true" failοnerrοr="true">
            <jvmarg value="-Dmaximum.inlined.code.length=32" />
            <arg value="-injars ${classes}" />
            <arg value="-outjars obfuscated.jar" />
            <arg value="-libraryjars ${androidjar}" />
  <arg value="-libraryjars C:\Users\edsheng\Desktop\wecheckscore\libs\library.jar" />
            <!-- 如果使用到外部库,请在这里指定 -->
<arg value="@proguard.cfg" />
  <arg value="-dump ${out}/dump.txt"/>
<arg value="-printusage ${out}/usage.txt"/>
<arg value="-printmapping ${out}/mapping.txt"/>
<arg value="-printseeds ${out}/seeds.txt"/>



</java>
           <delete dir="${classes}"/>
           <mkdir dir="${classes}"/>
           <unzip src="obfuscated.jar" dest="${classes}"/>
            <delete file="obfuscated.jar"/> 
<echo>代码混淆结束</echo>
</target>


需要注意的地方也是我红色的地方,指定外部混淆的jar,还有的一个是proguard.cfg这个文件,就是我们配置的文件我们还是打开这个文件看看,该怎么配置呢?

#-optimizationpasses 7
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-dontoptimize
-verbose
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers 
#-overloadaggressively


-keep public class  com.handmark.pulltorefresh.library.R*{*;}


#------------------  下方是android平台自带的排除项,这里不要动         ----------------
-keep public class * extends android.app.Activity{
public <fields>;
public <methods>;
}
-keep public class * extends android.app.Application
{
public <fields>;
public <methods>;
}


-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference


-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}


-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}


-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}


-keepattributes *Annotation*


# 改成这样,因为发现部分SDK中没有被java代码显示调用过,SO文件中调用的native方法会被混淆掉


-keepclasseswithmembers class * {
native <methods>;
}


-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}


#------------------  下方是共性的排除项目         ----------------
# 方法名中含有“JNI”字符的,认定是Java Native Interface方法,自动排除
# 方法名中含有“JRI”字符的,认定是Java Reflection Interface方法,自动排除


-keepclasseswithmembers class * {
    ... *JNI*(...);
}


-keepclasseswithmembernames class * {
... *JRI*(...);
}


-keep class **JNI* {*;}


需要注意的也是红色的部分,提示了不要混淆lib的R文件,最后就是我们的res文件资源的打包了,然后我们也来看看我们的脚本应该是怎么写的吧。

<!-- 打包项目的资源文件 -->
<target name="package_res_with_assets">
<echo>打包资源和资产文件...</echo>
<exec executable="${aapt}" failοnerrοr="true">
<arg value="package" />
 <arg value="--auto-add-overlay"></arg>
<arg value="-f" />
<arg value="-M" />
<arg value="AndroidManifest.xml" />
<arg value="-S" />
<arg value="res" />
<arg value="-S" />
<arg value="C:\Users\edsheng\Desktop\Android-PullToRefresh-master\library\res" />
<arg value="--extra-packages" /> 
<arg value="com.handmark.pulltorefresh.library"/>

<arg value="-A" />
<arg value="assets" />
<arg value="-I" />
<arg value="${androidjar}" />
<arg value="-F" />
<arg value="${out}/${file_name}.ap_" />
</exec>
<echo>打包资源和资产文件完成</echo>
</target>

还是红色的地方也是指定了外部的资源和lib这样外部工程的资源也被打包进来了。这样就可以不管是外部依赖一个还是多个都可以搞定了。那么大家就可以愉快的buld了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值