Android打包技术记录

当前各大渠道使用的打包技术在Eclipse项目的前提下无非就是通过母包与渠道资源合并,并重新打包生成APK。

Android apk文件其实就是一个以apk后缀的压缩包,由Android SDK下的工具编译生成。Android编译过程可通过下图了解;

使用压缩工具解压APK文件,可得到下图结构目录;

1、assets目录:assets目录里是项目对应的assets目录,原封不动;

2、lib目录:lib目录里会存放项目的各个框架的so文件,jar文件不会在里面,因为已经将jar文件编译;

3、META-INF目录:存放的是签名信息,用来保证apk包的完整性和系统的安全;

4、res目录:项目资源目录,该目录下的资源文件在项目中会一一对应生成R.java的资源引用;

5、AndroidManifest.xml:二进制后的AndroidManifest.xml文件;

6、classes.dex:java源码编译后生成的java字节码文件;

7、resources.arsc:编译后的二进制资源文件;

Ok,大概文件中的内容就这么多,那么进行打包流程中,我们需要使用一些Android SDK工具进行打包;

Android SDK目录

那么现在就解析打包过程的具体步骤吧:

1、apktool工具可将apk进行反编译。使用apktool工具,将母包进行反编译,得到一个母包反编译目录,反编译目录如:

2、反编译后得到我们的母包资源,然后对应目录,将渠道资源的资源assets目录,libs目录,res目录中的资源一一对应拷贝到母包资源目录中,jar文件不用拷贝,待会会进行编译,编译后的smali文件拷贝到smali文件目录中即可;

  将jar文件编译成smali文件步骤为:

  1、jar==>dex:"java" -jar -Xms1024m -Xmx1024m "dx.jar" --no-warning --dex --multi-dex --output="output_path" "jar_file_list"

  解析:1、java:就是JDK环境咯;2、dx.jar:Android SDK下的工具;3、output_path:输出路径;4、jar_file_list:jar文件,可多个jar文件,以空格隔开;

  2、dex==>smali:"java" -jar "baksmali.jar" -o ".../decompile/smali" "classes.dex"

  解析:1、java:同上;2、baksmali.jar:将dex编译成smali的工具;3、.../decompile/smali:smali文件输出目录,一般可直接输出到母包反编译smali目录中,因为smali文件有包目录路径,避免了再次的多文件夹拷贝;4、classes.dex:由1生成的dex文件;

3、代码文件基本上就搞定了,一个比较重要的就是,jar文件里,很多渠道会往jar文件里放文件,记得需要解压一下jar文件,然后遍历jar文件目录,如果里面有除了class文件的其他文件,需要拷贝出来,在jar文件根目录的直接拷贝到母包根目录中,其他的根据对应目录拷贝到母包对应目录即可,这个操作其实写个简单的脚本即可;

4、接下来,就是打包根据不同包的需求,修改应用名称,修改包名,修改ICON,修改版本号等等,这些都是修改文件的,没什么好讲的哈;

5、重新生成资源R文件,这个是整个打包过程的重点:"aapt" p -f -m -J "temp/gen" -S "temp/res" -I "android.jar" -M "decompile/AndroidManifest.xml"

  -f     如果编译出来的文件已经存在,强制覆盖
  -m   使生成的包的目录存放在-J参数指定的目录
  -J    指定生成的R.java 的输出目录 
  -S    res文件夹路径
  -I     某个版本平台的android.jar的路径
  -M   AndroidManifest文件路径
  -F    具体指定APK文件的输出 

6、R文件生成之后是java文件类型,通过javac编译成class文件: "javac" -source 1.7 -target 1.7 -encoding UTF-8 "R.java";然后同2步骤,将class文件编译成smali文件;

7、一些需要注意的地方:1、资源名称不能相同;2、框架armeabi与框架armeabi-v7a内容保持一致;

8、Ok,大概这些步骤都能解决掉大部分的需求了,现在就将母包目录进行回编译,同样是使用apktool工具;

9、签名、对齐优化;

打包流程大概就是这样了,这样可以将渠道资源跟母包资源合并在一起,现在大概打包都是这样操作;记录一下,以后用到就方便了;

 

——————————————————————————————————————————————————————————

 

记:

问题一:今天有个渠道打应用宝渠道的包时候总是,游戏运行不正常,加载资源时卡了,然后抛出ANR错误

原因:assets文件夹下的游戏文件被压缩了。Android Asset Packaging Tool(aapt)使用这个工具可打包所有数据 Image XML文件 任何资源文件.在生成APK时aapt选择性的压缩各种资源来节省设备空间,aapt使用后缀来决定哪个资源需要压缩,aapt源码定义一些不需要压缩的文件后缀。

view plainprint? 
  /* these formats are already compressed, or don't compress well */ 
  static const char* kNoCompressExt[] = { 
  ".jpg", ".jpeg", ".png", ".gif", 
  ".wav", ".mp2", ".mp3", ".ogg", ".aac", 
  ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet", 
  ".rtttl", ".imy", ".xmf", ".mp4", ".m4a", 
  ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2", 
  ".amr", ".awb", ".wma", ".wmv" 
  };

那么其他文件就会被压缩。在使用apktool工具的情况下,在apktool.yml下有个doNotCompress节点,在这里可以配置打包时忽略压缩的文件。通过配置,游戏文件不会被压缩,就正常了。

配置例如:

doNotCompress:
- arsc
- sfd
- esa

 

posted @ 2018-11-02 15:55  JhonMr  阅读(735)  评论(0编辑  收藏  举报