前言
笔者从事了几年的android开发,对android-app开发略有些心得,但是从未尝试过脱离IDE开发过 Android程序,故此翻阅了一些材料,才发现stackoverflow上有不错的一些资料。特此尝试翻译过来,一来希望可以帮助到初学者,二来笔者发现脱离了IDE开发 Android程序有助于理解其编译打包的过程。其过程就如用记事本写C语言程序,然后在拥有C编译环境下编译出目标(.o)文件,然后连接库成为一个完成的exe可执行文件。
开发步骤
1.环境要求及工具列表
- Oracle JDK 1.7或者最新版本
Android SDK Tools (只需要命令行工具部分。没错!脱离IDE进行开发,然后用命令行进行编译)
本案例中假定使用的是linux环境,如果不是linux环境,请自行配置命令行环境。如:window中需要把工具路径配置到系统变量中。
2.安装Android SDK并运行(如果已经对SDK很熟悉或者已经有相关的环境变量,请直接跳过第二步)
将SDK管理器压缩包解压以后,进行如下步骤:
- 使用SDK manager下载最新的命令行工具。这里需要注意:千万不要使用命令
android update sdk --no-ui
来更新SDK 工具,而是用SDK manager来进行最小化下载,即只下载推荐的最小下载包即可。因为前者会的下载包高达30G,在国内这种网速的情况下要下载n天才能完成。 把关于SDK和JDk的路径配置到系统环境变量中,需要添加到系统环境的路径如列表所示:
- JDK/bin
- SDK/platform-tools
- SDK/tools
- SDK/build-tools/LATEST (和第一步的安装步骤一致)
ps:JDK和SDK代表着你存放JDK和SDK的路径。
使用AVD Manager(也叫Android AVD)来创建一个 Android虚拟机。当然,你也可以使用自己的真机进行测试,这一步不是很重要。请略过。
使用一下命令启动虚拟机。
emulator -avd DEVICE
启动以后可以使用体验下里面的功能。
3.APP代码开发
- 切换到一个空的工作目录(或者新建一个文件夹)
输入以下命令建立新的资源文件及代码文件:
mkdir --parents src/dom/domain touch src/dom/domain/SayingHello.java
在SayingHello文件中输入以下内容:
package dom.domain; import android.widget.TextView; public final class SayingHello extends android.app.Activity { public void onCreate( final android.os.Bundle activityState ) { super.onCreate( activityState ); final TextView textV = new TextView( SayingHello.this ); textV.setText( "Hello world" ); setContentView( textV ); } }
在工程目录下创建Manifest.xml文件
touch AndroidManifest.xml
输入以下内容:
<?xml version='1.0'?> <manifest xmlns:a='http://schemas.android.com/apk/res/android' package='dom.domain' a:versionCode='0' a:versionName='0'> <application a:label='Saying hello'> <activity a:name='dom.domain.SayingHello'> <intent-filter> <category a:name='android.intent.category.LAUNCHER'/> <action a:name='android.intent.action.MAIN'/> </intent-filter> </activity> </application> </manifest>
创建资源文件目录res:
mkdir res
先放着为空,等需要资源的时候再放进去。
编译工程代码
在编译之前,务必把下面的命令换成自己的环境变量,然后用命令将声明的文件生成对应的资源。
aapt package -f \ -I SDK/platforms/android-API/android.jar \ -J src -m \ -M AndroidManifest.xml -S res -v
其中SDK为自己的SDK路径,如:xxx/android/ 结果就为:xxx/android/platforms/android-API/android.jar
因为咱们的示例很简单,对于android来说资源文件是可选的,所以以上的命令并没有生成实质的资源,也就是空的。
关于aapt命令,可以自行查找官方文档,这里推荐文章:
http://blog.csdn.net/androidzhaoxiaogang/article/details/8246713
编译代码文件,生成字节码文件(.java -> .class),命令如下:
javac \ -bootclasspath SDK/platforms/android-API/android.jar \ -classpath src -source 1.7 -target 1.7 \ src/dom/domain/*.java
将字节码转换成android dex格式的字节码,步骤如下:
第一步,使用Jill工具将.class文件转换为.jayce:
java -jar SDK/build-tools/LATEST/jill.jar \ --output classes.jayce src
第二步,使用Jack工具将.jayce文件转换为.dex:
java -jar SDK/build-tools/LATEST/jack.jar \ --import classes.jayce --output-dex .
至此,咱们已经将java文件编译,生成所需的dex文件
在以上的步骤中,你可以使用Jack 工具直接将.java编译转换为.dex文件,即一步完成。但是官方并没有推荐这个方法,因为javac使用上更加广泛而且有很好的文档社区支持
将所有的资源文件打包到一个地方,包括manifest.xml 文件,命令行如下:
aapt package -f \ -F app.apkPart \ -I SDK/platforms/android-API/android.jar \ -M AndroidManifest.xml -S res -v
经过以上的步骤,我们到的了apk文件的资源文件部分,即app.apkPart。
使用ApkBuilder工具将dex和资源文件打包成apk文件,命令如下:
java -classpath SDK/tools/lib/sdklib.jar \ com.android.sdklib.build.ApkBuilderMain \ app.apkUnalign \ -d -f classes.dex -v -z app.apkPart
但是,这里会产生一个警告:THIS TOOL IS DEPRECATED. See --help for more information.
,如果使用--help失败,而且异常是ArrayIndexOutOfBoundsException,那么可以一下命令:
java -classpath SDK/tools/lib/sdklib.jar \
com.android.sdklib.build.ApkBuilderMain
这里看到,第二行的时候是没有\参数的。
网上有文章说使用ApkBuilderMain过时了,应该直接使用ApkBuilder命令。
使用zipalign优化APK,即让资源文件的访问符合Data structure alignment标准(这个以后再展开讨论)
zipalign -f -v 4 app.apkUnalign app.apk
至此,咱们已经得到了一个未经前面但是已经可以运行的apk,也就是可以直接安装运行啦。
apk安装与运行
使用adb工具安装apk
adb install -r app.apk
用命令行启动android APP
adb shell am start -n dom.domain/.SayingHello
如果顺利,这个程序将会打印一个hello world到屏幕上。
至此,咱们已经完成了脱离IDE开发android app的目的。整个过程并没有使用高大上的IDE环境,而是直接使用记事本进行代码书写,用系统的工具来编译、转换、打包最后得到apk程序。
jack & jill 已经停了,还是用javac + dx吧
aapt2已经有了