当前位置:   article > 正文

写你自己 android 多通道打包工具 可以包libs和.so文件

android 源码支持多通道播放


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。

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

  1. package com.yang.main;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.io.InputStreamReader;
  10. import java.io.OutputStreamWriter;
  11. /**
  12. * @description: android渠道打包工具类,确保路径填写无误,渠道名称填入channels中
  13. * @author: hytfly@gamil.com
  14. * @time: 2012-10-23下午5:17:47
  15. */
  16. public class CompiledApkUpdate {
  17. private static final String androidSDK_PATH = "D:\\android\\android-sdk-windows\\"; //android SDK路径
  18. public static final String APK_NAME = "duitang.apk";
  19. public static final String PROJECT_LIBARY = "";
  20. public static final String PROJECT_PATH = "D:\\android\\workspace\\tmp\\duitang\\"; //要打包的project路径
  21. public static final String APK_PATH = "D:\\android\\workspace\\tmp\\apk\\duitang_"; //打包后存放apk的路径 duitang_是前缀
  22. private static final String apk_PATH_keystore = "D:\\android\\keystore\\bb"; //apk签名文件路径
  23. private static final String channelFlag = "app_channel";
  24. // public static String[] channels = {"duitang"};
  25. private static String currentChannelName = "";
  26. 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"};
  27. public static void main(String[] args) {
  28. replaceChannel();
  29. }
  30. /**
  31. * 替换渠道名称
  32. */
  33. public static void replaceChannel() {
  34. try {
  35. String outPath = PROJECT_PATH + "res\\values\\strings.xml"; // 输出文件位置
  36. String content = read(outPath);
  37. for(int channelid=0;channelid<channels.length;channelid++){
  38. String tmpContent = content;
  39. tmpContent = tmpContent.replaceFirst(channelFlag, channels[channelid]);
  40. currentChannelName = channels[channelid];
  41. write(tmpContent,outPath);
  42. System.out.println("replace channel name over...");
  43. packageRes(); // 一次渠道号的更改完毕。能够进行打包了。
  44. createUnsignedApk();
  45. signedApk(channelid);
  46. }
  47. write(content,outPath); //完毕后还原channel_name
  48. System.out.println("execute over!");
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. /**
  54. * class文件打包成classes.dex
  55. */
  56. public static void packageDex(){
  57. try {
  58. System.out.println("dx.bat start...");
  59. Process process = Runtime.getRuntime().exec(androidSDK_PATH
  60. +"platform-tools\\dx.bat --dex --output="
  61. +PROJECT_PATH+"bin\\classes.dex "
  62. +PROJECT_PATH+"bin\\classes "
  63. +PROJECT_PATH+"libs\\*.jar");
  64. new MyThread(process.getErrorStream()).start();
  65. new MyThread(process.getInputStream()).start();
  66. process.waitFor();
  67. process.destroy();
  68. System.out.println("dx.bat over...");
  69. } catch (Exception e) {
  70. e.printStackTrace();
  71. }
  72. }
  73. /**
  74. * res assets文件打包成res.zip
  75. */
  76. public static void packageRes(){
  77. try{
  78. System.out.println(currentChannelName+" create resources.ap");
  79. String library = "";
  80. if(PROJECT_LIBARY!=null&&!PROJECT_LIBARY.equals("")){
  81. library = "-S " + PROJECT_LIBARY + "res ";
  82. }
  83. Process process = null;
  84. process = Runtime
  85. .getRuntime()
  86. .exec( androidSDK_PATH
  87. + "platform-tools\\aapt.exe package -f " +
  88. "-M " + PROJECT_PATH + "AndroidManifest.xml " + //-M 指定配置文件
  89. "-S " + PROJECT_PATH + "res " + //-S 指定资源文件
  90. library +
  91. "-A " + PROJECT_PATH + "assets " + //-A 指定assets
  92. "-I " + androidSDK_PATH + "platforms\\android-16\\android.jar " + //-I 指定android类
  93. "-F " + PROJECT_PATH + "bin\\resources.ap_ --auto-add-overlay"); // 将资源文件打包resources.ap_
  94. new MyThread(process.getErrorStream()).start();
  95. new MyThread(process.getInputStream()).start();
  96. process.waitFor();
  97. process.destroy();
  98. System.out.println(currentChannelName+" resources.ap over...");
  99. }catch(Exception e){
  100. e.printStackTrace();
  101. }
  102. }
  103. /**
  104. * classes.dex res.zip AndroidManifest.xml组合成未签名的apk
  105. */
  106. public static void createUnsignedApk(){
  107. try{
  108. System.out.println(currentChannelName+" createUnsignedApk start");
  109. Process process = null;
  110. process = Runtime.getRuntime().exec(
  111. androidSDK_PATH+ "tools\\apkbuilder.bat "
  112. + PROJECT_PATH + "bin\\"+APK_NAME+" -u -z "
  113. + PROJECT_PATH + "bin\\resources.ap_ -f "
  114. + PROJECT_PATH + "bin\\classes.dex"
  115. +" -rj "+ PROJECT_PATH + "libs" //这里非常重要假设要打包libs的jar包请增加到上面字符串
  116. +" -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(); } } } }



版权声明:本文博客原创文章,博客,未经同意,不得转载。



本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4638162.html,如需转载请自行联系原作者


本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/317151
推荐阅读
相关标签
  

闽ICP备14008679号