老铁们,大家好,相信还有很多朋友对于Android手动命令行编译APK和的相关问题不太懂,没关系,今天就由我来为大家分享分享Android手动命令行编译APK以及的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!
在日常开发过程中为了提高效率,大多数开发者喜欢使用集成开发工具,比如Android Studios、Eclipse等。效率得到了提升,但一些基本原则却常常被忽视。现在我们抛开这些工具,通过打包命令手动编译APK。
APK解压
不知道你是否知道,APK实际上是一个zip格式的文件。我们将app.apk的后缀名改为app.zip,然后使用unzip进行解压。
如图所示:
解压后得到如下重要文件。
resources.arsc : AAPT 编译的资源索引表文件。
AndroidMainfest.xml:编译出来的压缩文件包含了一些应用程序信息,如包名、版本号、权限、组件注册等。
res目录:存放APP资源,包括图片、字符串、布局等文件。
源码编译后生成的classes.dex:java java字节码文件。
META-INF目录:存放签名信息,用于保证apk包的完整性和系统的安全。
编译过程
我们都知道一个基本的Android项目是由Mainifest、Resources、Assets、Sourcescode、Libraries等组成的,那么它们是如何构建的呢?看下面这张来自Google官方的经典流程图。
打包资源文件并生成R.java。应用程序资源通过aapt工具生成编译资源和R.java。
编译aidl并将其转换为java Interfaces文件。如果项目中没有aidl文件,则忽略此步骤。
编译所有.java源代码文件并生成.class字节码文件。 java编译器会使用源代码文件,aapt生成的R.java,aidl编译的java
编译成.class 文件。
转换所有类文件并生成.dex 文件。使用dex工具将项目中编译好的.class文件和第三方类库生成.dex文件。
生成未签名的.apk 文件。通过apkbuider将编译好的资源文件和.dex文件生成.apk
生成签名的.apk 文件。使用jarsigner 命令从未签名的apk 生成签名的apk
优化签名apk文件。使用zipalign工具将所有资源文件的距离调整为4字节的整数倍,这样文件访问会更快。
--create project子命令的用法如下:
[普通] 查看普通副本
选项:
-n --name 应用程序的名称
-t --target SDK 目标ID
-p --path 应用程序的工作目录
-k --package 应用程序的包名称
-a --activity 默认创建的Activity的名称
创建的工程文件列表如下:
手工包装
了解了打包流程之后,我们通过一个例子来手动验证一下。手动创建以下文件。结构如下:
安卓项目/
AndroidManifest.xml
创/
库/
android-support-v4.jar
出/
资源/
可绘制-xhdpi/
图标.png
可绘制-xxhdpi/
图标.png
可绘制-xxxhdpi/
图标.png
布局/
Activity_main.xml
源文件/
cn/
安卓博客/
测试构建/
MainActivity.java
第一步:资源编译
使用aapt工具。 aapt命令网上有很多,这里不再赘述。
jomeslu@jomeslu:~$ aapt 包-f
-M AndroidManifest.xml
-I '$ANDROID_HOME/platforms/android-N/android.jar'
-S 分辨率/
-Jgen/
-m
然后生成的R.java在gen/cn/androidblog/testbuild/R.java文件中
/* 自动生成的文件。请勿修改。
* 这个类是由系统自动生成的
* aapt工具从它找到的资源数据中。它
* 不应手动修改。
*/
包com.androidblog.testbuild;
公开最终课R {
公共静态最终类属性{
}
公共静态最终类可绘制{
公共静态最终int ic_launcher=0x7f020000;
}
公共静态最终类布局{
公共静态最终int Activity_main=0x7f030000;
}
}
适参数
-f 如果编译的文件已经存在,则强制覆盖。
-m 将生成的包的目录放置在-J 参数指定的目录中。
-J 指定生成的R.java的输出目录
-S res文件夹路径
-断言文件夹的路径
-M AndroidManifest.xml 的路径
-I 某版本平台的android.jar路径
-F 指定输出apk文件
第二步:代码编译
通过javac将java文件编译成.class文件。命令如下:
jomeslu@jomeslu:~$ javac
-编码GBK
-bootclasspath /home/jomeslu/Android/Sdk/platforms/android-22/android.jar
-d ./testBuild/out/
./testBuild/src/com/androidblog/testbuild/*.java
./testBuild/gen/com/androidblog/testbuild/*.java
-classpath ./testBuild/libs/android-support-v4.jar
在out/cn/androidblog/testbuild/目录下的.class中
注:javac的参数
-g 生成所有调试信息
-g:none 不生成任何调试信息
-g:{lines,vars,source} 只生成某些调试信息
-nowarn 不生成任何警告
-有关编译器正在执行的操作的详细输出消息
- 弃用使用已弃用API 的输出源位置
-classpath 路径指定在哪里查找用户类文件和注释处理程序
-cp path 指定在哪里查找用户类文件和注释处理程序
-sourcepath 路径指定查找输入源文件的位置
-bootclasspath 路径覆盖引导类文件的位置
-extdirs 目录覆盖已安装扩展的位置
-endorseddirs 目录覆盖签名标准路径的位置
-proc:{none,only} 控制是否执行注释处理和/或编译。
-processor[,] 绕过默认搜索过程
-processorpath路径指定在哪里找到注释处理器
-parameters 生成元数据以反映方法参数
-d 目录指定放置生成的类文件的位置
-s 目录指定放置生成的源文件的位置
-h目录指定放置生成的本机头文件的位置
-implicit:{none,class} 指定是否为隐式引用的文件生成类文件
-encoding 指定源文件使用的字符编码
-source distribution 提供与指定发行版的源兼容性
-target distribution 为特定VM版本生成类文件
-profile 配置文件请确保所使用的API在指定的配置文件中可用
-version 版本信息
-help 打印标准选项的摘要
-A 关键字[=值] 传递给注释处理程序的选项
-X 输出非标准选项的摘要
-J flag 将标志直接传递给运行时系统
-Werror 出现警告时终止编译
@filename 从文件中读取选项和文件名
步骤3:生成.dex文件
将项目out目录下的所有文件编译成classes.dex文件。通过dex工具编译,网上查看详细的dx命令。
jomeslu@jomeslu:~$ ./dx
--dex --output=./testBuild/out/classes.dex
./testBuild/out/cn/androidblog/testbuild/
例如:使用Android SDK提供的dx.bat命令行脚本生成classes.dex文件,将项目bin目录下的class文件编译成classes.dex。 Android虚拟机只能执行dex文件!
使用Android SDK提供的aapt.exe生成资源包文件(包括res、assets、androidmanifest.xml等)
使用AndroidSDK提供的apkbuilder工具生成未签名的APK文件
第四步:生成APK文件
此阶段分为两步:1.资源文件初始打包2.添加classes.dex
资源文件初始包
jomeslu@jomeslu:~$ aapt 包-f
-M AndroidManifest.xml
-I /home/jomeslu/Android/Sdk/platforms/android-22/android.jar
-S 分辨率/
-F 输出/testbuildresc.apk
使用apkbuilder工具将testbuildresc.apk添加到classes.dex文件中
jomeslu@jomeslu:~$ apkbuilder ./testbuild/out/testbuild_unsinger.apk
-v
-u
-z ./testbuild/out/testbuildresc.apk
-f ./testbuild/out/classes.dex
-rf ./testbuild/src
-nf ./testbuild/libs
-rj ./testbuild/libs
第5步:添加签名
大家都知道apk必须经过签名。无论是debug签名还是公版签名,都需要安装,否则无法安装使用。
注意:1,如果需要将so文件打包成apk,必须添加-nf参数
2、如果第三方jar包中含有图片资源,一定要加上-rj参数,否则无法解码jar包中的资源文件,程序会因为无法引用资源而报错!
SDK提供了debug key,路径为~/.android/debug.keystore。
默认签名信息如下
密钥密码: android
密钥库密码: android
密钥alias: androiddebugkey
所以使用JDK提供的工具jarsigner来签名
jomeslu@jomeslu:~$ jarsigner -verbose
-keystore ~/.android/debug.keystore
-storepass 安卓
-keypass Android
./testbuild/out/testbuild.apk
android调试密钥
这样APK就已经被签名了。
第6步:优化签名的APK
例如:
这是最后一步。 APK签名完成后,未压缩的数据需要在4字节边界上对齐。这样就提高了APK的性能,主要体现在文件操作、资源读取等方面。使用Zipalign工具可以帮助我们处理这样的事情。
jomeslu@jomeslu:~$ zipalign
-f 4 ./testbuild/out/testbuild.apk ./testbuild/out/testbuild-optimized.apk
总结
包装过程很容易理解。总结一下以下3部分
资源编译
编译java源代码并生成.class
打包和优化APK
用户评论
终于找到这篇文章了!我一直想学习如何手动编译 APK,但网上教程都非常复杂,你的文章讲解很简单易懂,图片也很详细。
有5位网友表示赞同!
说的对,有时候用 IDEA 虽然方便,但是你真的要想深入了解代码和打包流程,还是得多依靠命令行操作。这篇博文总结得很不错!
有6位网友表示赞同!
Android 手动命令行编译 APK 这块东西我真没太接触过,看起来确实有点复杂啊,下次有机会尝试下!
有10位网友表示赞同!
之前用 Android Studio 的快速打包,现在才知道原来还有手动编译的方式,真是打开了新世界大门!不过感觉这种方式还是比较适合有一定 Android 开发基础的人学习。
有6位网友表示赞同!
写的挺好的,把关键步骤都概括了,建议再补充一些常见问题解答,比如遇到构建错误的解决方法等等,
有18位网友表示赞同!
其实手动编译 APK 本身并不复杂,就是需要掌握一些基本的命令行操作和 Android SDK 的知识。 就像学习任何新的技能一样,都需要一点时间和耐心。 这篇文章讲解得很清晰,对入门阶段的人很有帮助!
有12位网友表示赞同!
这种方法是不是比直接用 Android Studio 打包慢很多啊?我看这篇文章里写的好像步骤好多呀,感觉耗时应该很长 ?
有20位网友表示赞同!
这篇博文提到了很多我之前没注意过的细节,比如使用哪个版本的 SDK、哪些工具需要下载等等。受益匪浅!
有16位网友表示赞同!
手工编译确实比较适合对底层机制了解的人,对于我们这种习惯用界面操作的开发者来说,还是直接用 Android Studio 更方便一些吧
有20位网友表示赞同!
我觉得你这个方法很有意思,能让我们更深入地理解 APK 的打包过程。建议在文章里添加更多关于定制化打包的技巧,比如如何修改构建参数、添加第三方库等等。
有6位网友表示赞同!
之前遇到一个特殊情况,手动编译 apk 成功了,而 IDEA 直接打包就失败了,现在回想起来应该是这个原因! 感谢分享!
有13位网友表示赞同!
感觉这篇文章有点“高深莫测”,我还没学过命令行操作呢!希望以后有时间学习下,体验这种手动编译的过程
有10位网友表示赞同!
你说的没错,手工编译 APK 真的可以让我们更熟悉 Android 的构建流程。 之前一直用 IDEA 直接打包,现在开始研究一下命令行的使用方法了,觉得很有成就感!
有11位网友表示赞同!
这个方法确实比较专业,对新手小白来说可能有点 overwhelming, 建议再添加一些针对初学者的指导,比如一些常见的错误解决方法等等
有13位网友表示赞同!
对于学习 Android 开发的伙伴来说,手动编译 APK 是一项非常重要的技能。 这篇文章写的很详细,帮我避免了很多不必要的时间浪费。非常感谢分享!
有7位网友表示赞同!
其实我还是更喜欢使用 IDE 打包,觉得更加直观易操作。 手动命令行编译感觉太麻烦了,需要记忆很多命令和参数,而且调试也比较费力
有14位网友表示赞同!
我个人认为这种手动编译的方式更有利于理解整个打包过程,因为它让我们亲身体验每一个步骤的过程,而不是仅仅依赖于 IDE 的自动化工具。 这篇文章讲解得很好,帮我理清了思路
有17位网友表示赞同!
这篇文章确实很有用,对我学习 Android 开发非常有帮助!感谢作者的分享!
有20位网友表示赞同!