Android多渠道打包工具
2015-04-15 16:06
369 查看
Android市场众多,要监测每个渠道的数据的,需根据不同的渠道打包,该工具可以一步为各个渠道打包成不同的
建立Java项目运行,即可(下面代码都有详细的介绍)。
/**
* Android多渠道打包工具
* 1、确保路径填写无误,渠道名称填入channels中
* 2、运行之前确保bin文件夹下有最新的apk
* 3、AndroidManifest.xml.xml中修改 <meta-data android:name="UMENG_CHANNEL" android:value="@string/channel_name" />
* 4、res\strings.xml中修改 <string name="channel_name">app_channel<//string>
*
*/
public class CompiledApkUpdate {
//市场别名{搜狗手机助手,搜狐,360,木蚂蚁,91,豌豆荚,小米,搜狗,魅族,QQ,百度,联想,机锋,安智,N多网}
public static String[] channels = { "sougouzs", "sohu", "360", "mumayi",
"91", "wandoujia", "mi", "sougou", "meizu", "QQ", "baidu",
"lenovo", "gfan", "anzhi", "nduoa" };
//默认名称
public static final String APK_NAME = "hsj_temp.apk";
//要打包工程的根目录
public static final String PROJECT_PATH = "E:\\WorkSoftwareWorkspace\\androidDemo\\DrawNumber\\";
//生成的apk存放位置,huashijie_是前缀
public static final String APK_PATH = "E:\\numberapk\\yqhsj_";
//资源包
public static final String PROJECT_LIBARY = "";
private static String currentChannelName = "";
//Android sdk路径
private static final String androidSDK_PATH = "E:\\WorkSoftwareWorkspace\\android-sdk-windows-1.5_r1\\"; // android
//apk签名文件
private static final String apk_PATH_keystore = "E:\\app_signature\\apkkey.keystore";
//签名密码
private static final String key_storepass = "111111";
//别名密码
private static final String alias_keypass = "111111";
//别名名称
private static final String alias_name = "通用的密匙";
//对应strings.xml中的配置
private static final String channelFlag = "app_channel";
public static void main(String[] args) {
replaceChannel();
}
/**
* 替换渠道名称
*/
public static void replaceChannel() {
try {
String outPath = PROJECT_PATH + "res\\values\\strings.xml"; // 输出文件位置
String content = read(outPath);
for (int channelid = 0; channelid < channels.length; channelid++) {
String tmpContent = content;
tmpContent = tmpContent.replaceFirst(channelFlag,
channels[channelid]);
currentChannelName = channels[channelid];
write(tmpContent, outPath);
System.out.println("replace channel name over...");
packageRes(); // 一次渠道号的更改完成。可以进行打包了。
createUnsignedApk();
signedApk(channelid);
}
write(content, outPath); // 完成后还原channel_name
System.out.println("execute over!");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* class文件打包成classes.dex
*/
public static void packageDex() {
try {
System.out.println("dx.bat start...");
Process process = Runtime.getRuntime().exec(
androidSDK_PATH + "platform-tools\\dx.bat --dex --output="
+ PROJECT_PATH + "bin\\classes.dex " + PROJECT_PATH
+ "bin\\classes " + PROJECT_PATH + "libs\\*.jar");
new MyThread(process.getErrorStream()).start();
new MyThread(process.getInputStream()).start();
process.waitFor();
process.destroy();
System.out.println("dx.bat over...");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* res assets文件打包成res.zip
*/
public static void packageRes() {
try {
System.out.println(currentChannelName + " create resources.ap");
String library = "";
if (PROJECT_LIBARY != null && !PROJECT_LIBARY.equals("")) {
library = "-S " + PROJECT_LIBARY + "res ";
}
Process process = null;
process = Runtime.getRuntime().exec(
androidSDK_PATH
// + "platform-tools\\aapt.exe package -f " +
+ "build-tools\\19.0.0\\aapt.exe package -f "
+ "-M " + PROJECT_PATH
+ "AndroidManifest.xml "
+ // -M 指定配置文件
"-S " + PROJECT_PATH
+ "res "
+ // -S 指定资源文件
library + "-A " + PROJECT_PATH
+ "assets "
+ // -A 指定assets
"-I " + androidSDK_PATH
+ "platforms\\android-16\\android.jar "
+ // -I 指定android类
"-F " + PROJECT_PATH
+ "bin\\resources.ap_ --auto-add-overlay"); // 将资源文件打包resources.ap_
new MyThread(process.getErrorStream()).start();
new MyThread(process.getInputStream()).start();
process.waitFor();
process.destroy();
System.out.println(currentChannelName + " resources.ap over...");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* classes.dex res.zip AndroidManifest.xml组合成未签名的apk
*/
public static void createUnsignedApk() {
try {
System.out.println(currentChannelName + " createUnsignedApk start");
Process process = null;
process = Runtime.getRuntime().exec(
androidSDK_PATH + "tools\\apkbuilder.bat " + PROJECT_PATH
+ "bin\\" + APK_NAME + " -u -z " + PROJECT_PATH
+ "bin\\resources.ap_ -f " + PROJECT_PATH
+ "bin\\classes.dex"); // 生成未签名的apk
new MyThread(process.getErrorStream()).start();
new MyThread(process.getErrorStream()).start();
process.waitFor();
process.destroy();
System.out.println(currentChannelName + " createUnsignedApk over");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 签名apk
*/
public static void signedApk(int channelid) {
try {
System.out.println(currentChannelName + " signed apk start");
Process process = null;
String jarsigner;
jarsigner = "jarsigner -keystore " + apk_PATH_keystore
+ " -storepass "+key_storepass+" -keypass "+alias_keypass+" " + "-signedjar "
+ APK_PATH + channels[channelid] + ".apk " + PROJECT_PATH
+ "bin\\" + APK_NAME +" "+ alias_name; // 签名apk
process = Runtime.getRuntime().exec(jarsigner); // 对apk进行签名
new MyThread(process.getErrorStream()).start();
new MyThread(process.getInputStream()).start();
process.waitFor();
process.destroy();
System.out.println(currentChannelName + " signed apk over"); // 一条渠道的打包完成。文件会输出到指定目录
} catch (Exception e) {
e.printStackTrace();
}
}
public static String read(String path) {
StringBuffer res = new StringBuffer();
String line = null;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(path), "UTF-8"));
while ((line = reader.readLine()) != null) {
res.append(line + "\n");
}
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return res.toString();
}
public static boolean write(String cont, String dist) {
try {
OutputStreamWriter writer = new OutputStreamWriter(
new FileOutputStream(new File(dist)), "utf-8");
writer.write(cont);
writer.flush();
writer.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static class MyThread extends Thread {
BufferedReader bf;
public MyThread(InputStream input) {
bf = new BufferedReader(new InputStreamReader(input));
}
public void run() {
String line;
try {
line = bf.readLine();
while (line != null) {
System.out.println(line);
line = bf.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
建立Java项目运行,即可(下面代码都有详细的介绍)。
/**
* Android多渠道打包工具
* 1、确保路径填写无误,渠道名称填入channels中
* 2、运行之前确保bin文件夹下有最新的apk
* 3、AndroidManifest.xml.xml中修改 <meta-data android:name="UMENG_CHANNEL" android:value="@string/channel_name" />
* 4、res\strings.xml中修改 <string name="channel_name">app_channel<//string>
*
*/
public class CompiledApkUpdate {
//市场别名{搜狗手机助手,搜狐,360,木蚂蚁,91,豌豆荚,小米,搜狗,魅族,QQ,百度,联想,机锋,安智,N多网}
public static String[] channels = { "sougouzs", "sohu", "360", "mumayi",
"91", "wandoujia", "mi", "sougou", "meizu", "QQ", "baidu",
"lenovo", "gfan", "anzhi", "nduoa" };
//默认名称
public static final String APK_NAME = "hsj_temp.apk";
//要打包工程的根目录
public static final String PROJECT_PATH = "E:\\WorkSoftwareWorkspace\\androidDemo\\DrawNumber\\";
//生成的apk存放位置,huashijie_是前缀
public static final String APK_PATH = "E:\\numberapk\\yqhsj_";
//资源包
public static final String PROJECT_LIBARY = "";
private static String currentChannelName = "";
//Android sdk路径
private static final String androidSDK_PATH = "E:\\WorkSoftwareWorkspace\\android-sdk-windows-1.5_r1\\"; // android
//apk签名文件
private static final String apk_PATH_keystore = "E:\\app_signature\\apkkey.keystore";
//签名密码
private static final String key_storepass = "111111";
//别名密码
private static final String alias_keypass = "111111";
//别名名称
private static final String alias_name = "通用的密匙";
//对应strings.xml中的配置
private static final String channelFlag = "app_channel";
public static void main(String[] args) {
replaceChannel();
}
/**
* 替换渠道名称
*/
public static void replaceChannel() {
try {
String outPath = PROJECT_PATH + "res\\values\\strings.xml"; // 输出文件位置
String content = read(outPath);
for (int channelid = 0; channelid < channels.length; channelid++) {
String tmpContent = content;
tmpContent = tmpContent.replaceFirst(channelFlag,
channels[channelid]);
currentChannelName = channels[channelid];
write(tmpContent, outPath);
System.out.println("replace channel name over...");
packageRes(); // 一次渠道号的更改完成。可以进行打包了。
createUnsignedApk();
signedApk(channelid);
}
write(content, outPath); // 完成后还原channel_name
System.out.println("execute over!");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* class文件打包成classes.dex
*/
public static void packageDex() {
try {
System.out.println("dx.bat start...");
Process process = Runtime.getRuntime().exec(
androidSDK_PATH + "platform-tools\\dx.bat --dex --output="
+ PROJECT_PATH + "bin\\classes.dex " + PROJECT_PATH
+ "bin\\classes " + PROJECT_PATH + "libs\\*.jar");
new MyThread(process.getErrorStream()).start();
new MyThread(process.getInputStream()).start();
process.waitFor();
process.destroy();
System.out.println("dx.bat over...");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* res assets文件打包成res.zip
*/
public static void packageRes() {
try {
System.out.println(currentChannelName + " create resources.ap");
String library = "";
if (PROJECT_LIBARY != null && !PROJECT_LIBARY.equals("")) {
library = "-S " + PROJECT_LIBARY + "res ";
}
Process process = null;
process = Runtime.getRuntime().exec(
androidSDK_PATH
// + "platform-tools\\aapt.exe package -f " +
+ "build-tools\\19.0.0\\aapt.exe package -f "
+ "-M " + PROJECT_PATH
+ "AndroidManifest.xml "
+ // -M 指定配置文件
"-S " + PROJECT_PATH
+ "res "
+ // -S 指定资源文件
library + "-A " + PROJECT_PATH
+ "assets "
+ // -A 指定assets
"-I " + androidSDK_PATH
+ "platforms\\android-16\\android.jar "
+ // -I 指定android类
"-F " + PROJECT_PATH
+ "bin\\resources.ap_ --auto-add-overlay"); // 将资源文件打包resources.ap_
new MyThread(process.getErrorStream()).start();
new MyThread(process.getInputStream()).start();
process.waitFor();
process.destroy();
System.out.println(currentChannelName + " resources.ap over...");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* classes.dex res.zip AndroidManifest.xml组合成未签名的apk
*/
public static void createUnsignedApk() {
try {
System.out.println(currentChannelName + " createUnsignedApk start");
Process process = null;
process = Runtime.getRuntime().exec(
androidSDK_PATH + "tools\\apkbuilder.bat " + PROJECT_PATH
+ "bin\\" + APK_NAME + " -u -z " + PROJECT_PATH
+ "bin\\resources.ap_ -f " + PROJECT_PATH
+ "bin\\classes.dex"); // 生成未签名的apk
new MyThread(process.getErrorStream()).start();
new MyThread(process.getErrorStream()).start();
process.waitFor();
process.destroy();
System.out.println(currentChannelName + " createUnsignedApk over");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 签名apk
*/
public static void signedApk(int channelid) {
try {
System.out.println(currentChannelName + " signed apk start");
Process process = null;
String jarsigner;
jarsigner = "jarsigner -keystore " + apk_PATH_keystore
+ " -storepass "+key_storepass+" -keypass "+alias_keypass+" " + "-signedjar "
+ APK_PATH + channels[channelid] + ".apk " + PROJECT_PATH
+ "bin\\" + APK_NAME +" "+ alias_name; // 签名apk
process = Runtime.getRuntime().exec(jarsigner); // 对apk进行签名
new MyThread(process.getErrorStream()).start();
new MyThread(process.getInputStream()).start();
process.waitFor();
process.destroy();
System.out.println(currentChannelName + " signed apk over"); // 一条渠道的打包完成。文件会输出到指定目录
} catch (Exception e) {
e.printStackTrace();
}
}
public static String read(String path) {
StringBuffer res = new StringBuffer();
String line = null;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(path), "UTF-8"));
while ((line = reader.readLine()) != null) {
res.append(line + "\n");
}
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return res.toString();
}
public static boolean write(String cont, String dist) {
try {
OutputStreamWriter writer = new OutputStreamWriter(
new FileOutputStream(new File(dist)), "utf-8");
writer.write(cont);
writer.flush();
writer.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static class MyThread extends Thread {
BufferedReader bf;
public MyThread(InputStream input) {
bf = new BufferedReader(new InputStreamReader(input));
}
public void run() {
String line;
try {
line = bf.readLine();
while (line != null) {
System.out.println(line);
line = bf.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
相关文章推荐
- Android apk多渠道自动打包 - 不提供工具,只提供源码
- android多渠道打包工具
- Android Multi channel package tool (安卓多渠道打包工具)
- Android多渠道打包工具
- Android多渠道打包工具Gradle插件
- Android多种多渠道打包工具对比
- Android QA专用,Python实现不一样的多渠道打包工具
- Android多渠道打包工具
- Android apk多渠道自动打包 - 不提供工具,只提供源码
- Android apk多渠道自动打包 - 不提供工具,只提供源码
- 自己写 android 多渠道打包工具 可打包libs和.so文件
- 自制的android多渠道应用打包工具--RyApkTool(1)
- android多渠道打包牛B工具
- ant工具-多渠道自动打包android项目
- android 多渠道打包工具 可打包libs和.so文件
- 自制的android多渠道应用打包工具--RyApkTool(2)
- android 7.0 多渠道打包 - 美团开源工具Walle 命令行打包
- Android QA专用,Python实现不一样的多渠道打包工具
- Android apk多渠道自动打包 - 不提供工具,只提供源码
- Android多渠道打包(三):美团多渠道打包