写你自己 android 多通道打包工具 可以包libs和.so文件
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文件的更多相关文章
- 基于apktool项目的android批量打包工具,多平台支持
好久木有写博客了,今天有点兴致就写一下,献上一个没怎么用的批量打包工具,python实现的,虽然说现在android的批量打包有一个很好的工具可以使用gradle,这个灰常牛叉的工具和android ...
- Android自动打包工具aapt详解
概念 在Android.mk中有LOCAL_AAPT_FLAGS配置项,在gradle中也有aaptOptions,那么aapt到底是干什么的呢? aapt即Android Asset Packagi ...
- Android将Activity 打 jar包 (解决资源文件不能打包的问题)
转载地址:http://blog.csdn.net/xiaanming/article/details/9257853 最近有一个需要,我们公司做了一个apk客户端,然后其他的公司可以根据自己的需要来 ...
- 以libfuse为例介绍rpm打包工具rpmbuild的使用和SPEC文件的编写
一.rpmbuild命令的安装 yum install rpm-build 二.用法 rpmbuild -bb XXXX.spec或者rpmbuild -ba XXX.tar.gz 三.目录概述 rp ...
- Android Studio打包SDK后,为什么没有bundles文件夹?
在Android Studio中,将项目打包成jar包,按照网上说的方法打包完成后,在intermediates文件夹下没有bundles,AS版本3.1.2,后来发现,原来是intermediate ...
- 如何打包/运行jar包,及生成exe文件
关于如何打包/运行jar包,以及生成exe文件.之前各种查询.博客,终于搞明白究竟是咋回事.记得还做过笔记的.今天要打包生成exe用的时候,居然忘了咋怎来着.去查看之前的笔记,死活没找到(好像被删掉了 ...
- Android多渠道打包工具
http://www.cnblogs.com/huangtianhui/archive/2012/07/14/2591382.html 鉴于Android市场众多,基于各种利益考虑,以及未来app能够 ...
- 五 Android Studio打包Eegret App (包名和签名,打出正式包)
一 定义包名 如下图,在AndroidManifest.xml中的package就是包名 二 创建keystore 选择Build->Generate Signed APK 选择create n ...
- Android Studio打包未签名包
Android Studio打包未签名包 好久没有写技术博客了,真有点懈怠了,作为35岁的程序员,转行重新捡起这些知识,还是挺犹豫纠结的,不过没啥其它办法,一点一滴开始吧,今天这开篇就小结点前几天工作 ...
随机推荐
- 代写java程序qq:928900200
学校为全面提升学校教学质量,提高管理水平,决定开发一套小型成绩管理系统,实现以下功能.1) 系统用户分为管理员.教师和学生三种角色,每种角色都可以包含若干个用户.其中管理员登录后可以进行教师.学生 ...
- IIS的WebGarden、WebFarm和StateServer
开启IIS的WebGarden.WebFarm和StateServer之旅 前言 公司系统虽然配置有1台NLB后拖4台App Server最后搭一台强劲无比的DB Server,但每天下午4点左右总被 ...
- 做web项目时对代码修改后浏览器端不生效的应对方法(持续更新)
做web项目时,经常会遇到修改了代码,但浏览器端没有生效,原因是多种多样的,我会根据我遇到的情况逐步更新解决办法 1.运行的时候采用debug模式,一般情况下使用项目部署按钮右边那个按钮下的tomca ...
- BootStrap -- Grid System
<script src="jquery.1.9.js"></script> <script src="js/bootstrap.min.js ...
- CoreGraphics QuartzCore CGContextTranslateCTM 说明
CoreGraphics.h 一些经常使用旋转常量 #define M_E 2.71828182845904523536028747135266250 e #define M_LOG2E 1.442 ...
- Duanxx的Design abroad: C++矩阵运算库Eigen 概要
一.概要 这两天想起来要做神经网络的作业了,要求用C++完毕神经网络的算法. 摆在面前的第一个问题就是,神经网络算法中大量用到了矩阵运算.可是C++不像matlab那样对矩阵运算有非常好的支持.本来准 ...
- cocos2dX 它CCScene创建原则和切换模式
今天, 让我们来看看现场CCScene创建原则和切换模式, 首先, 个什么样子: 我们先来看看效果: 啥也没有: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZX ...
- [Python 学习] 两、在Linux使用平台Python
在本节,它介绍了Linux如何使用平台Python 1. Python安装. 今天,大多数把自己的版本号Python的,它不能被安装.假设你要安装它,可以使用相应的安装指令. Fedora:先以roo ...
- Appium之java API
AppiumDriver getAppStrings() 默认系统语言相应的Strings.xml文件内的数据. driver.getAppStrings(String language) 查找某一个 ...
- epoll演示样本
server参考是别人的代码 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include ...