您的位置:首页 > 移动开发 > Android开发

通过命令行实现Android工程资源文件到apk的流程

2016-09-27 19:39 731 查看
前言

命令行演示Android工程项目资源的编译打包流程
本篇文章的环境

相关工具地址

创建Android工程文件

生成Rjava

编译java2class

class2dex

打包资源文件

生成未签名的apk

生成签名秘钥

apk签名

异常总结

参考文章

前言

我们在开发Android应用的时候,可能很少研究整个Apk生成的过程,一般如AS或者Eclipse的开发工具,在运行的时候会自动帮我们将代码与资源文件打包并签名,生成相应的apk文件,不知道大家有没有好奇整个apk的编译、打包过程呢,下面通过这篇文章,一块来了解一下一个Android的工程文件是怎么从代码、资源文件变成最终的apk文件的。

命令行演示Android工程项目资源的编译打包流程

参考官方文档的流程图,下面我们通过命令行手动的模拟一下整个流程:



本篇文章的环境

首先我的操作系统是基于Windows系统,JDK版本最终使用的是1.6(以上会出现异常),sdk-tools版本是21。

相关工具地址

JDK下载地址

apkbuilder下载地址

创建Android工程文件

进入tools文件夹:

cd D:\eclipse\sdk\tools


命令行:

[android.bat] --target [target_id] --name [project_name] --path [project_path] --package [package_name] --activity[activity_name]


这些参数代表的意思:

占位符描述本文示例
target_idsdk版本每个人电脑上面根据安装的版本不同,id对应的版本也不同,我电脑上的的8,即API21
project_name工程名称resource2apk
project_path工程路径D:\CSDN\
package_name包名com.csdn.lhy
activity_name创建Activity的名称MainActivity
D:\eclipse\sdk\tools\android.bat create project --target 8  --name source2apk --path D:\CSDN\ --package com.csdn.lhy --activity MainActivity


运行结果如下,可以看到在相应的目录下,已经创建了该工程,注意此时是没有gen目录的,也就是说此时还没有生成R文件。



生成R.java

接下来,我们通过命令行处理相应的资源文件,来生成R文件。

命令行:

[aapt.exe] -f -m -J [gen_folder_path] -S [res_path] -I [android.jar_path] -M [manifest_path]


占位符描述本文示例
aapt.exeaapt工具路径D:\eclipse\sdk\build-tools\build-tools-21.1.1\aapt.exe
gen_folder_pathgen目录路径D:\CSDN\gen
res_pathres资源文件路径D:\CSDN\res
android.jar_path覆盖引导类文件的位置D:\eclipse\sdk\platforms\android-21\android.jar
manifest_pathAndroidManifest.xml文件位置D:\CSDN\AndroidManifest.xml
D:\eclipse\sdk\build-tools\build-tools-21.1.1\aapt.exe

D:\eclipse\sdk\build-tools\build-tools-21.1.1\aapt.exe package  -f -m -J D:\CSDN\gen -S D:\CSDN\res -I D:\eclipse\sdk\platforms\android-21\android.jar -M D:\CSDN\AndroidManifest.xml


执行之后看到如下,在相应的gen目录下面,生成了R.java文件,注意到第一次这个命令行执行失败,需要人工创建一下gen目录,第二次执行成功,打开R文件,看到里面已经生成了相应的代码。



编译.java2.class

编译java文件生成class ,不要忘记R.java文件

注意:
-bootclasspath
是必须要设置的, 它表示覆盖引导类文件的位置,如果不设置会报错,命令行如下:

javac -target [jdk_version] -bootclasspath [android.jar_path] -d [.java_path]


占位符描述本文示例
jdk_versionjdk的版本1.6
android.jar_path覆盖引导类文件的位置D:\eclipse\sdk\platforms\android-21\android.jar
.java_path.java文件的位置即src文件下的.java以及gen目录下的R.java
javac -target 1.6 -bootclasspath D:\eclipse\sdk\platforms\android-21\android.jar -d D:\CSDN\bin D:\CSDN\src\com\csdn\lhy\*.java D:\CSDN\gen\com\csdn\lhy\R.java


运行成功的话,如下图所示,在bin目录下生成了相应的.class文件,注意不要忽略了R.java



我们通过JD-GUI打开看一下,发现可以
c3cc
正常的反编译回来。



.class2.dex

class打包成dex,需要注意的是,dx工具最好使用创建项目中的sdk版本中的,与bootclasspath所用版本一致,命令行如下:

[dx.bat] --dex --output=[dex_path] [classes_path]


占位符描述本文示例
dx.batdx工具的位置D:\eclipse\sdk\build-tools\build-tools-21.1.1\dx.bat
dex_path打包后dex文件的生成路径D:\CSDN\bin\classes.dex
classes_path当前的.class字节码文件路径D:\CSDN\bin\
D:\eclipse\sdk\build-tools\build-tools-21.1.1\dx.bat

D:\eclipse\sdk\build-tools\build-tools-21.1.1\dx.bat --dex --output= D:\CSDN\bin\classes.dex D:\CSDN\bin\


运行成功之后,结果如下图,我们发现在bin目录下已经生成了相应的dex文件:



打包资源文件

打包资源文件,将资源文件打包成resources.ap_文件,命令行如下:

[aapt.exe] package -f -m -S [res_path] -I [android.jar_path] -M[manifest_path] -F[resources.ap_]


占位符描述本文示例
aapt.exeaapt.exe路径D:\eclipse\sdk\build-tools\build-tools-21.1.1\aapt.exe
res_path项目中res资源文件位置D:\eclipse\sdk\platforms\android-21\android.jar
android.jar_path覆盖引导类文件的位置D:\CSDN\bin\
manifest_pathAndroidManifest.xml文件路径D:\CSDN\AndroidManifest.xml
resources.ap_打包资源文件生成的resources.ap_文件路径D:\CSDN\bin\resources.ap_
D:\eclipse\sdk\build-tools\build-tools-21.1.1\aapt.exe package  -f -m -S D:\CSDN\res -I D:\eclipse\sdk\platforms\android-21\android.jar -M D:\CSDN\AndroidManifest.xml -F D:\CSDN\bin\resources.ap_


运行结果如下:



生成未签名的apk

最终打包apk,需要使用apkbuilder.bat 必须放到tools文件夹下面:

[apkbuilder.bat] [unsigned_apk_path] -v -u -z [resources.ap_] -f [classes.dex] -rf [src_path]


占位符描述本文示例
apkbuilder.batapkbuilder.bat路径D:\eclipse\sdk\tools\apkbuilder.bat
unsigned_apk_path生成的未签名apk文件路径D:\CSDN\bin\final.apk
resources.ap_打包资源文件生成的resources.ap_文件路径D:\CSDN\bin\resources.ap_
classes.dexclasses.dex文件路径D:\CSDN\bin\classes.dex
src_pathsrc文件夹路径D:\CSDN\src
D:\eclipse\apkbuilder.bat

D:\eclipse\sdk\tools\apkbuilder.bat D:\CSDN\bin\final.apk -v -u -z D:\CSDN\bin\resources.ap_ -f D:\CSDN\bin\classes.dex -rf D:\CSDN\src


我们可以看到运行成功后,在相应的文件下生成了未签名的apk文件。



生成签名秘钥

创建密匙,会在当前
C:\Users\用户名\
文件下下生成相应的签名证书文件:

keytool -genkey -alias release -keyalg RSA -validity 20000 -keystore release.keystore


apk签名

jarsigner -verbose -keystore [keystore_path] -storepass [password] -keypass [password] android -signedjar [signed_apk] [unsigned_apk] release


占位符描述本文示例
keystore_path签名证书路径C:\Users\memphise\release.keystore
password签名中自己设定的密码我设置的是android
signed_apk最终生成的签名之后的apk文件路径D:\CSDN\bin\resource2jar-signed.apk
unsigned_apk需要签名的apk文件路径D:\CSDN\bin\final.apk
jarsigner -verbose -keystore C:\Users\memphise\release.keystore -storepass android -keypass android -signedjar D:\CSDN\bin\resource2jar-signed.apk D:\CSDN\bin\final.apk release


运行结果如图,在bin目录下,生成了刚才签名的apk文件。



我们在模拟器上安装一下,可以看到运行成功,Hello World



异常总结

在将class文件打包成dex文件时候遇到:

com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)


这是由于jdk版本与dx工具版本不一致的问题,解决方案参考了stackoverflow ,原本我的JDK版本是1.8,这里打包的时候就遇到了这个问题,最终降级到1.6之后解决了这个问题。

至于Eclipse,AS等工具,使用1.6版本以上的JDK仍然可以打包成功,有哪位大神可以告知一下么?

参考文章

Android 命令行手动编译打包详解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android