AS打包全攻略

时间:2021-05-02 08:40:44

1、为什么要打包

    我最开始就有这个疑问,我们的代码不是点了下运行按钮就直接安装到手机上了吗,我们在在项目Project目录的build/outputs/apk目录下可以找到刚刚新鲜生成的app-debug.apk.直接把这个上传给市场不就行了吗。

AS打包全攻略

   NO,当然不行,想想手机安装App的时候怎么来区分各个APK的。
通过包名+签名 来确定一个应用的唯一性,那个debug.apk只是系统用来给我们调试用的,如果上传到市场,怎么来保证他的安全性。

   OK,我们已经解决了第一步—怎么打包。上传上去后,市场反馈发现我们的App写得太棒了,这时候老大让赶快多上些平台,主流的平台、非主流的平台都要放上去。
那么问题来了,为了方便统计各个平台的安装情况,配合运营推广,需要统计各个平台的安装情况。

2、分渠道打包

不错,我们需要用到分渠道打包,那么我们需要解决两个问题
1. 怎么区分各个平台的标识
2. 怎么每次版本更新都生成几十个包、几百个包
第一个简单,用过友盟打包的同学肯定不陌生这段代码

[java]  view plain  copy  print ?
  1. <code class="hljs haskell"><meta-data android:name="UMENG_CHANNEL" android:value="Channel_ID"></meta-data></code>  
     value里面填的就是各个平台的值,比如填写uc、yyb(应用宝)、360、baidu替换掉Channel_ID,App安装好,可以读取这个值然后传给后台,从而实现区分各个平台的安装需求。
    第二个问题:
    在Eclipse时代,最开始我是手动打的,一次打30个包,每次最怕版本更新,基本一下午都在做机械运动,现在想起来手都在抽筋。后来,学会了Ant自动打包,快倒是快,只是配置太坑爹了,超级麻烦。现在有了Android Studio,妈妈再也不用担心我不能愉快的打包了。随便新建一个项目,修改Module:app build.gradle为

[java]  view plain  copy  print ?
  1. <code class="hljs livecodeserver">apply plugin: 'com.android.application'  
  2. android {  
  3.     signingConfigs {  
  4.         config {  
  5.             keyAlias 'maker'  
  6.             keyPassword '1234make'  
  7.             storeFile file('/Users/Nevermore/AndroidStudioProjects/Blog/jks/makeapp.jks')  
  8.             storePassword 'make1234'  
  9.         }  
  10.     }  
  11.     compileSdkVersion 23  
  12.     buildToolsVersion "23.0.3"  
  13.     defaultConfig {  
  14.         applicationId "com.example.makeapp"  
  15.         minSdkVersion 15  
  16.         targetSdkVersion 23  
  17.         versionCode 1  
  18.         versionName "1.0"  
  19.     }  
  20.     buildTypes {  
  21.         debug {  
  22.             minifyEnabled false  
  23.             debuggable true  
  24.         }  
  25.    
  26.         release {  
  27.             minifyEnabled true  
  28.             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'  
  29.             signingConfig signingConfigs.config  
  30.             debuggable false  
  31.         }  
  32.     }  
  33.     productFlavors {  
  34.         uc {  
  35.             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "uc"]  
  36.         }  
  37.         _360 {  
  38.             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "360"]  
  39.         }  
  40.         baidu {  
  41.             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]  
  42.         }  
  43.         yyb {  
  44.             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "yyb"]  
  45.         }  
  46.     }  
  47. }  
  48.    
  49. dependencies {  
  50.     compile fileTree(dir: 'libs', include: ['*.jar'])  
  51.     testCompile 'junit:junit:4.12'  
  52.     compile 'com.android.support:appcompat-v7:23.3.0'  
  53. }</code>  

    我们需要配置:

signingConfigs这是刚才我们新建的密匙信息 buildTypes 打包类型,包括了Debug和Release productFlavors打包渠道就在这儿配置咯 同时在AndroidManifest里面加上,渠道标识
[java]  view plain  copy  print ?
  1. <code class="hljs r"><manifest package="example.com.makeapk" xmlns:android="http://schemas.android.com/apk/res/android">  
  2.    
  3.     <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}">  
  4.     ...省略  
  5. </meta-data></manifest></code>  

3、现在还有个问题—代码写完了怎么生成渠道包呢
OK,在命令行输入 gradlew assembleRelease,表示生成所有Release包,生成的包在build\outputs\apk目录下,如果你要生成指定的包(uc|360|baidu),指定的版本(Release|Debug),右边的Gradle Project可以帮到你

AS打包全攻略

4、删除多余的 unaligned.apk
执行完-gradlew assembleRelease,发现一个问题,生成的不仅有我们需要的包,unaligned.apk类型的Apk也输出来了

AS打包全攻略

    unaligned.apk 是还没执行对齐命令的包,是中间形态,这个需要删除,没必要不知道为什么Gradle没有帮我们删了这没啥用的玩意儿,问题是我们也不想一个一个的手动删除。好吧,写了一个脚本命令,在输出文件夹的命令行执行如下:

[java]  view plain  copy  print ?
  1. <code class="hljs lasso"> find . -name "*-unaligned.apk" | xargs rm -rf</code>  

5、优化gradle代码
    刚才写的代码

[java]  view plain  copy  print ?
  1. <code class="hljs perl">  productFlavors {  
  2.         uc {  
  3.             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "uc"]  
  4.         }  
  5.         _360 {  
  6.             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "360"]  
  7.         }  
  8.         baidu {  
  9.             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]  
  10.         }  
  11.         yyb {  
  12.             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "yyb"]  
  13.         }  
  14.     }</code>  
    减少我们的代码量
[java]  view plain  copy  print ?
  1. <code class="hljs avrasm">    productFlavors {  
  2.         uc {}  
  3.         _360 {}  
  4.         baidu {}  
  5.         yyb {}  
  6.     }  
  7.     productFlavors.all { flavor ->  
  8.         flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]  
  9.     }</code>  

6. Gradle对新人来说语法有学习曲线,能不能再容易一点

咱们有工具啊,打开顶部Build

AS打包全攻略

选择红色部分,里面的编辑框可以帮助我们更快的熟悉Gradle

AS打包全攻略

AS打包全攻略

AS打包全攻略

AS打包全攻略

来看看代码和编辑框的具体关系吧

AS打包全攻略


7. 打包太多,需要清理一下

AS打包全攻略

8、直接修改渠道号

想想,如果只是打渠道包的话,没有必要对整个项目进行编译,来生成渠道号。
如果能直接修改apk的渠道号,而不需要再重新签名能节省不少打包的时间。幸运的是我们找到了这种方法。直接解压apk,解压后的根目录会有一个META-INF目录。
如果在META-INF目录内添加空文件,可以不用重新签名应用。因此,通过为不同渠道的应用添加不同的空文件,可以唯一标识一个渠道。
采用这种方式,每打一个渠道包只需复制一个apk,在META-INF中添加一个使用渠道号命名的空文件即可。
这种打包方式速度非常快,900多个渠道不到一分钟就能打完。
没错,这就是美团的打包策略

使用方式:https://github.com/GavinCT/AndroidMultiChannelBuildTool
使用本工具,Android程序员仅需将ChannelUtil.Java放入到工程里使用,以后打包的事情就不用自己动手了。
安装个Python环境,运行一下MultiChannelBuildTool.py,谁都可以打包了!
毕竟实践是检验真理的唯一标准:
拷贝一个,我们刚刚生成的app-uc-release.apk到项目目录

AS打包全攻略

反编译看看,包打得对不对,命令行

[java]  view plain  copy  print ?
  1. <code class="hljs avrasm">apktool d xxx.apk</code>  
AS打包全攻略
打开目录,首先确认我们生成的XML里面的标识符

AS打包全攻略

然后看到,美团极速打包方案也完成

AS打包全攻略