A tool class for compiling Android projects using command lines
A tool class for compiling Android projects using command lines
The following tools are used to compile an apk project ):
1.aapt.exe
Resource packaging tool 2. android. jar
Android compilation tool 3. dx. bat
Dex file generation tool 4. sdklib. jar
Generate apk 5. jarsigner
Signature Tool
Preparation
The environment required before packaging is as follows:
1. JDK1.6 +
2. Android SDK
3. Path of the above five tools
Packaging Process
1. Generate the R. java File
For example:
aapt package -f -m -J ./gen -S res -M AndroidManifest.xml -I D:\android_sdk_for_studio\platforms\android-22\android.jar
2. Clear the bin directory
Clear the last generated file
3. Compile the java file and jar package
javac -encoding GBK -target 1.5 -bootclasspath D:\android_sdk_for_studio\platforms\android-22\android.jar -d bin src\net\mobctrl\normal\apk\*.java gen\net\mobctrl\normal\apk\R.java -classpath libs\*.jar
4. Use the dx tool to package it into classes. dex
dx --dex --output=C:\Users\mochuan.zhb\newworkspace\BundleApk5\bin\classes.dex C:\Users\mochuan.zhb\newworkspace\BundleApk5\bin\
5. Compile the resource source file
aapt package -f -M AndroidManifest.xml -S res -I D:\android_sdk_for_studio\platforms\android-22\android.jar -F bin\resources.ap_ --non-constant-id
6. Use sdklib. jar to generate unsigned apk
java -cp D:\android_sdk_for_studio\tools\lib\sdklib.jar com.android.sdklib.build.ApkBuilderMain bin\MyCommond.apk -v -u -z bin\resources.ap_ -f bin\classes.dex -rf C:\Users\mochuan.zhb\newworkspace\BundleApk5\src
7. Use jarsigner to sign the apk
Jarsigner-verbose-keystore C: \ test. keystore-storepass 123456-keypass 123456-signedjar C: \ projectdemo-signed.apk C: \ test.apk test
BuildApkUtils source code, automatically generate and execute commands
Package com. taobao. trip; import java. io. file; import java. io. fileWriter; import java. io. IOException; import java. io. printWriter; import java. util. arrayList; import java. util. arrays; import java. util. comparator; import java. util. list;/*** @ Author Zheng Haibo (mochuan) * @ Company Alibaba Group * @ PersonalWebsite http://www.mobctrl.net * @ version $ Id: BuildUtils. java, v 0.1 January 8, 2016 8:47:42 mochuan. zhb Exp $ * @ Description on the Windows platform, how to use the command line to compile the android project */public class BuildApkUtils {private static final String ANDROID_JAR_PATH = "D: \ android_sdk_for_studio \ platforms \ android-22 \ android. jar "; private static final String AAPT_PATH =" D: \ mochuan. zhb \ android-sdks \ build-tools \ 22.0.1 \ aapt_alitrip.exe "; private static final String DX_PATH =" D: \ android_sdk_for_studio \ build-tools \ 22.0.1 \ dx. bat "; private static final String SDK_LIB_JAR_PATH =" D :\\ android_sdk_for_studio \ tools \ lib \ sdklib. jar "; private static final String batchDir = System. getProperty ("user. dir ") +" \ batch \ "; private String projectDir; private int packageId = 127; public BuildApkUtils () {} public BuildApkUtils (String projectDir) {this. projectDir = projectDir;} public BuildApkUtils (String projectDir, int packageId) {this. projectDir = projectDir; this. packageId = packageId;} public void buildUnsingedApk () {clearDir (batchDir); clearDir (projectDir + "\ bin"); generateR (projectDir, packageId); compileJavaFiles (projectDir ); buildDexFile (projectDir); complieResources (projectDir, packageId); buildUnsignedApk (projectDir, "unsigned.apk"); mergeExeBatchFiles ();}/*** Step 1: generate the R file ** @ param projectDir * @ param packageId */private static void generateR (String projectDir, int packageId) {StringBuffer command = new StringBuffer (); command. append (AAPT_PATH ). append ("package-f-m-J "). append (projectDir ). append ("\ gen "). append ("-S "). append (projectDir ). append ("\ res "). append ("-M "). append (projectDir ). append ("\ AndroidManifest. xml "). append ("-"). append (projectDir ). append ("\ assets "). append ("-I "). append (ANDROID_JAR_PATH ). append ("-- non-constant-id-x -- package-id "). append (packageId); buildExeBatchFiles (command. toString (), "1.bat");}/*** compile the java file ** @ param projectDir */private static void compileJavaFiles (String projectDir) {StringBuffer command = new StringBuffer (); command. append ("javac-target 1.5-bootclasspath "). append (ANDROID_JAR_PATH ). append ("-d "). append (projectDir ). append ("\ bin"); List
JavaFilePaths = new ArrayList
(); FindJavaFiles (projectDir + "\ src", javaFilePaths); findJavaFiles (projectDir + "\ gen", javaFilePaths); for (String javaPath: javaFilePaths) {command. append (javaPath ). append ("");} command. append ("-classpath "). append (projectDir ). append ("\ libs \\. * jar "); buildExeBatchFiles (command. toString (), "2.bat");}/*** create dex file ** @ param projectDir */private static void buildDexFile (String projectDir) {StringBuffer command = new StringBuffer (); command. append (DX_PATH ). append ("-- dex -- output = "). append (projectDir ). append ("\ bin \ classes. dex "). append (""). append (projectDir ). append ("\ bin"); buildExeBatchFiles (command. toString (), "3.bat");}/*** compile the resource file ** @ param projectDir */private static void complieResources (String projectDir, int packageId) {StringBuffer command = new StringBuffer (); command. append (AAPT_PATH ). append ("package-f-M "). append (projectDir ). append ("\ AndroidManifest. xml "). append ("-S "). append (projectDir ). append ("\ res "). append ("-I "). append (ANDROID_JAR_PATH ). append ("-"). append (projectDir ). append ("\ assets "). append ("-F "). append (projectDir ). append ("\ bin \ resources. ap _"). append ("-- non-constant-id-x -- package-id "). append (packageId); buildExeBatchFiles (command. toString (), "4.bat");}/*** generate unsigned apk ** @ param projectDir * @ param apkName */private static void buildUnsignedApk (String projectDir, String apkName) {StringBuffer command = new StringBuffer (); command. append ("java-cp "). append (SDK_LIB_JAR_PATH ). append ("com. android. sdklib. build. apkBuilderMain "). append (projectDir ). append ("\ bin \\"). append (apkName ). append ("-v-u-z "). append (projectDir ). append ("\ bin \ resources. ap _"). append ("-f "). append (projectDir ). append ("\ bin \ classes. dex "). append ("-rf "). append (projectDir ). append ("\ src"); buildExeBatchFiles (command. toString (), "5.bat");}/*** recursive search ** @ param projectDir * @ param javaFilePaths */private static void findJavaFiles (String projectDir, List
JavaFilePaths) {File file = new File (projectDir); File [] files = file. listFiles (); if (files = null | files. length = 0) {return;} for (File f: files) {if (f. isDirectory () {findJavaFiles (f. getAbsolutePath (), javaFilePaths);} else {if (f. getAbsolutePath (). endsWith (". java ") {javaFilePaths. add (f. getAbsolutePath () ;}}}/*** clear directory ** @ param projectDir */private static void clearDir (S Tring projectDir) {File file = new File (projectDir); File [] files = file. listFiles (); if (files = null | files. length = 0) {return;} for (File f: files) {if (f. isDirectory () {clearDir (f. getAbsolutePath ();} else {f. delete () ;}}/*** create a batch file ** @ param command * @ param file */private static void buildExeBatchFiles (String command, String fileName) {System. out. println (command); if (! New File (batchDir ). exists () {new File (batchDir ). mkdirs ();} String filePath = batchDir + fileName; try {writeFile (filePath, command);} catch (IOException e) {e. printStackTrace () ;}} private static void mergeExeBatchFiles () {File file = new File (batchDir); System. out. println ("debug: current path =" + file. getAbsolutePath (); File [] files = file. listFiles (); if (files = null | files. length = 0) {return;} Arrays. sort (files, new Comparator
() {Public int compare (File file1, File file2) {if (file1.lastModified ()> file2.lastModified () {return 1;} else if (file1.lastModified () <file2.lastModified ()) {return-1 ;}else {return 0 ;}}); StringBuffer command = new StringBuffer (); for (File f: files) {command. append ("call "). append (f. getAbsolutePath ()). append ("\ n");} try {String filePath = batchDir + "build. bat "; writeFile (filePath, command. toString (); runtime.getruntime(cmd.exe c ("cmd/c start" + filePath);} catch (Exception e) {e. printStackTrace () ;}/ *** Write File *** @ param filePath * @ param sets * @ throws IOException */private static void writeFile (String filePath, String content) throws IOException {FileWriter fw = new FileWriter (filePath); PrintWriter out = new PrintWriter (fw); out. write (content); out. println (); fw. close (); out. close ();}}
Use
During running, you only need to input the project path:
public class BuildMain { private static final String PROJECT_PATH = "C:\\Users\\mochuan.zhb\\newworkspace\\BundleApk5"; private static final int PACKAGE_ID = 5; public static void main(String[] args) { new BuildApkUtils(PROJECT_PATH, PACKAGE_ID).buildUnsingedApk(); }}
The generated command is printed during running:
D:\mochuan.zhb\android-sdks\build-tools\22.0.1\aapt_alitrip.exe package -f -m -J C:\Users\mochuan.zhb\newworkspace\BundleApk5\gen -S C:\Users\mochuan.zhb\newworkspace\BundleApk5\res -M C:\Users\mochuan.zhb\newworkspace\BundleApk5\AndroidManifest.xml -A C:\Users\mochuan.zhb\newworkspace\BundleApk5\assets -I D:\android_sdk_for_studio\platforms\android-22\android.jar --non-constant-id -x --package-id 5javac -target 1.5 -bootclasspath D:\android_sdk_for_studio\platforms\android-22\android.jar -d C:\Users\mochuan.zhb\newworkspace\BundleApk5\bin C:\Users\mochuan.zhb\newworkspace\BundleApk5\src\net\mobctrl\normal\apk\BaseActivity.java C:\Users\mochuan.zhb\newworkspace\BundleApk5\src\net\mobctrl\normal\apk\BundleActivity.java C:\Users\mochuan.zhb\newworkspace\BundleApk5\src\net\mobctrl\normal\apk\FileUtils.java C:\Users\mochuan.zhb\newworkspace\BundleApk5\src\net\mobctrl\normal\apk\Utils.java C:\Users\mochuan.zhb\newworkspace\BundleApk5\gen\net\mobctrl\normal\apk\BuildConfig.java C:\Users\mochuan.zhb\newworkspace\BundleApk5\gen\net\mobctrl\normal\apk\R.java -classpath C:\Users\mochuan.zhb\newworkspace\BundleApk5\libs\.*jarD:\android_sdk_for_studio\build-tools\22.0.1\dx.bat --dex --output=C:\Users\mochuan.zhb\newworkspace\BundleApk5\bin\classes.dex C:\Users\mochuan.zhb\newworkspace\BundleApk5\binD:\mochuan.zhb\android-sdks\build-tools\22.0.1\aapt_alitrip.exe package -f -M C:\Users\mochuan.zhb\newworkspace\BundleApk5\AndroidManifest.xml -S C:\Users\mochuan.zhb\newworkspace\BundleApk5\res -I D:\android_sdk_for_studio\platforms\android-22\android.jar -A C:\Users\mochuan.zhb\newworkspace\BundleApk5\assets -F C:\Users\mochuan.zhb\newworkspace\BundleApk5\bin\resources.ap_ --non-constant-id -x --package-id 5java -cp D:\android_sdk_for_studio\tools\lib\sdklib.jar com.android.sdklib.build.ApkBuilderMain C:\Users\mochuan.zhb\newworkspace\BundleApk5\bin\unsigned.apk -v -u -z C:\Users\mochuan.zhb\newworkspace\BundleApk5\bin\resources.ap_ -f C:\Users\mochuan.zhb\newworkspace\BundleApk5\bin\classes.dex -rf C:\Users\mochuan.zhb\newworkspace\BundleApk5\src