android上传应用程序,需要区分各个信道。

通常更改配置文件中的一个通道id,假设有多个通道,手动更改并生成apk这将是非常麻烦的,及增加误差的概率。

在这个课堂上分享一个打包工具。也可在网上类似的。我是做IT优化的基础上,,特别是封装so文件,一句小小的命令废了好大劲。

我们项目中使用的umeng做统计分析工具。 umeng在分渠道打包的时候须要改动manifest.xml中的

<meta-data  android:name="UMENG_CHANNEL" android:value="@string/channel_name" />  value值。

该值放到了strings.xml中<string name="channel_name">app_channel</string>,所以在编译的时候仅仅需改动app_channel。

以下是工具类,直接执行就可以.

package com.yang.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* @description: android渠道打包工具类,确保路径填写无误,渠道名称填入channels中
* @author: hytfly@gamil.com
* @time: 2012-10-23下午5:17:47
*/
public class CompiledApkUpdate { private static final String androidSDK_PATH = "D:\\android\\android-sdk-windows\\"; //android SDK路径 public static final String APK_NAME = "duitang.apk";
public static final String PROJECT_LIBARY = "";
public static final String PROJECT_PATH = "D:\\android\\workspace\\tmp\\duitang\\"; //要打包的project路径
public static final String APK_PATH = "D:\\android\\workspace\\tmp\\apk\\duitang_"; //打包后存放apk的路径 duitang_是前缀 private static final String apk_PATH_keystore = "D:\\android\\keystore\\bb"; //apk签名文件路径
private static final String channelFlag = "app_channel"; // public static String[] channels = {"duitang"};
private static String currentChannelName = "";
public static String[] channels = {"duitang","91","360","QQ","jifeng","anzhuo","anzhi","youyi","appchina","wangyi","baidu","souhu","3g","nduo","xiaomi","huawei","meizu","lianxiang","aliyun","taobao","google","nearme","mumayi","wandoujia","crosscat","dangle","maopao","feiliu"}; 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 " +
"-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"
+" -rj "+ PROJECT_PATH + "libs" //这里非常重要假设要打包libs的jar包请增加到上面字符串
+" -nf "+ PROJECT_PATH + "libs" //这里是我试了好多次翻阅各种资料才成功的,给大家分享了。 这样打包才干够把so文件也打包进去。
); // 生成未签名的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 ***** -keypass ****** " +
"-signedjar "
+ APK_PATH
+ channels[channelid]
+ ".apk "
+ PROJECT_PATH
+ "bin\\"+APK_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();
}
}
/**
* 这是google签名的打包方式。 跟上面一个方法差点儿相同的 zipalign apk
*/
public static void zipalignApk(int channelid){
try{
System.out.println(currentChannelName+":zipalign apk start");
String apkPath=APK_PATH.replace("{c}", channels[channelid]);
File file=new File(apkPath);
if(!file.getParentFile().isDirectory()) file.getParentFile().mkdirs();
Process process = null;
String jarsigner;
jarsigner = "cmd.exe /C "+androidSDK_PATH+"tools/zipalign.exe -v 4 "
+ apkPath
+ ".apk "
+ apkPath
+ "-z.apk"; //签名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+":zipalign apk over"); // 一条渠道的打包完毕。文件会输出到指定文件夹
}catch(Exception e){
e.printStackTrace();
System.exit(0);
}
} 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 多通道打包工具 可以包libs和.so文件的更多相关文章

  1. 基于apktool项目的android批量打包工具,多平台支持

    好久木有写博客了,今天有点兴致就写一下,献上一个没怎么用的批量打包工具,python实现的,虽然说现在android的批量打包有一个很好的工具可以使用gradle,这个灰常牛叉的工具和android ...

  2. Android自动打包工具aapt详解

    概念 在Android.mk中有LOCAL_AAPT_FLAGS配置项,在gradle中也有aaptOptions,那么aapt到底是干什么的呢? aapt即Android Asset Packagi ...

  3. Android将Activity 打 jar包 (解决资源文件不能打包的问题)

    转载地址:http://blog.csdn.net/xiaanming/article/details/9257853 最近有一个需要,我们公司做了一个apk客户端,然后其他的公司可以根据自己的需要来 ...

  4. 以libfuse为例介绍rpm打包工具rpmbuild的使用和SPEC文件的编写

    一.rpmbuild命令的安装 yum install rpm-build 二.用法 rpmbuild -bb XXXX.spec或者rpmbuild -ba XXX.tar.gz 三.目录概述 rp ...

  5. Android Studio打包SDK后,为什么没有bundles文件夹?

    在Android Studio中,将项目打包成jar包,按照网上说的方法打包完成后,在intermediates文件夹下没有bundles,AS版本3.1.2,后来发现,原来是intermediate ...

  6. 如何打包/运行jar包,及生成exe文件

    关于如何打包/运行jar包,以及生成exe文件.之前各种查询.博客,终于搞明白究竟是咋回事.记得还做过笔记的.今天要打包生成exe用的时候,居然忘了咋怎来着.去查看之前的笔记,死活没找到(好像被删掉了 ...

  7. Android多渠道打包工具

    http://www.cnblogs.com/huangtianhui/archive/2012/07/14/2591382.html 鉴于Android市场众多,基于各种利益考虑,以及未来app能够 ...

  8. 五 Android Studio打包Eegret App (包名和签名,打出正式包)

    一 定义包名 如下图,在AndroidManifest.xml中的package就是包名 二 创建keystore 选择Build->Generate Signed APK 选择create n ...

  9. Android Studio打包未签名包

    Android Studio打包未签名包 好久没有写技术博客了,真有点懈怠了,作为35岁的程序员,转行重新捡起这些知识,还是挺犹豫纠结的,不过没啥其它办法,一点一滴开始吧,今天这开篇就小结点前几天工作 ...

随机推荐

  1. Oracle SQL Lesson (11) - 创建其他数据库对象(试图/序列/索引/同义词)

    schema(模式)一个用户下一组对象的集合,一般与用户名一致. 视图 CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view [(alias[, alias].. ...

  2. android 网络运营商的名字显示规则(锁定屏幕,下拉列表)

    一:Background & 有关flow MTK Operator name display分为两种类型的手机: 1. Sim卡名称: 从基于引导SIM卡读取IMSI到Spn-conf.xm ...

  3. HTML5之Canvas影片广场

    HTML5之Canvas影片广场 1.设计源代码 <!DOCTYPE html> <head> <meta charset="utf-8" /> ...

  4. Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表

    本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...

  5. linux下一个Oracle11g RAC建立(五岁以下儿童)

    linux下一个Oracle11g RAC建立(五岁以下儿童) 四.建立主机之间的信任关系(node1.node2) 建立节点之间oracle .grid 用户之间的信任(通过ssh 建立公钥和私钥) ...

  6. C#和C++下数据类型对应表

    /C++中的DLL函数原型为//extern "C" __declspec(dllexport) bool 方法名一(const char* 变量名1, unsigned char ...

  7. 11gR2 Database Services for &quot;Policy&quot; and &quot;Administrator&quot; Managed Databases (文件 ID 1481647.1)

    In this Document   _afrLoop=1459311711568804&id=1481647.1&displayIndex=6&_afrWindowMode= ...

  8. 基本数据类型TypeScript

    TypeScript 前言 最近项目很急,所以没有什么时间回答关于Xamarin.Android方面的问题,也有一段时间没有更新.主要是手头很缺人,如果有谁有兴趣加入我们的话,可以私聊我,这样我就能继 ...

  9. 更改IOS于UISearchBar撤消button底、搜索输入文本框背景中的内容和UISearchBar底

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/39993433 測试的手机IOS系统版本为:6.1.3,实现过程例如以下: 1.加入U ...

  10. Android学习路径(七)建立Action Bar

    在action bar最今本的形式中,它只在左边展示了activity的标题以及应用的icon. 即使在这样的简单的形式中,它也不过告诉用户如今在应用的哪个activity中,同一时候为你的应用保持一 ...