转载:http://www.2cto.com/kf/201606/517300.html

初出茅庐 手动打包

怎么手动打包

项目写完了,现在需要把应用上传到市场,问题出现—怎么把代码变成.apk(Android的可安装文件)。
1. 创建签名文件

2. 填写好签名参数

3. 生成APK
注意:签名的密码和密匙的密码注意保管,不要忘了,签名文件别泄漏了,也别搞丢了

为什么要打包

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

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

渐入佳境 渠道打包

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

分渠道打包

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

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

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

我们需要配置:

signingConfigs这是刚才我们新建的密匙信息 buildTypes 打包类型,包括了Debug和ReleaseproductFlavors打包渠道就在这儿配置咯 同时在AndroidManifest里面加上,渠道标识

1
2
3
4
5
<code class="hljs r"><manifest package="example.com.makeapk" xmlns:android="http://schemas.android.com/apk/res/android">
 
    <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}">
    ...省略
</meta-data></manifest></code>

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

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

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

1
<code class="hljs lasso"> find . -name "*-unaligned.apk" | xargs rm -rf</code>

优化gradle代码
刚才写的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code class="hljs perl">  productFlavors {
        uc {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "uc"]
        }
        _360 {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "360"]
        }
        baidu {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
        }
        yyb {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "yyb"]
        }
    }</code>

有些冗余,修改下减少我们的代码量

1
2
3
4
5
6
7
8
9
<code class="hljs avrasm">    productFlavors {
        uc {}
        _360 {}
        baidu {}
        yyb {}
    }
    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }</code>

是不是美观多了
6. Gradle对新人来说语法有学习曲线,能不能再容易一点
咱们有工具啊,打开顶部Build

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




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

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

炉火纯青 恐弄快打

直接修改渠道号

想想,如果只是打渠道包的话,没有必要对整个项目进行编译,来生成渠道号。
如果能直接修改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到项目目录

  

果然厉害,1S就出来这么多包。

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

1
<code class="hljs avrasm">apktool d xxx.apk</code>

打开目录,首先确认我们生成的XML里面的标识符

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

但是,使用Gradle生成4个渠道,我们花了 26.5秒 人家 只花了目测 1s

1分钟900个包果然不是梦

Build Variants(构建变种版本)

待续…

登峰造极 打包安全

待续…

Android Studio打包全攻略的更多相关文章

  1. 【转】【Android】Android Studio打包全攻略

    项目写完了,现在需要把应用上传到市场,问题出现—怎么把代码变成.apk(Android的可安装文件).1. 创建签名文件2. 填写好签名参数3. 生成APK注意:签名的密码和密匙的密码注意保管,不要忘 ...

  2. 【转】Android Studio打包全攻略---从入门到精通

    原文地址:http://blog.csdn.net/zivensonice/article/details/51672846 初出茅庐 手动打包 怎么手动打包 项目写完了,现在需要把应用上传到市场,问 ...

  3. Android屏幕适配全攻略 (转载)

    http://blog.csdn.net/jdsjlzx/article/details/45891551 https://github.com/hongyangAndroid/AndroidAuto ...

  4. Android使用XML全攻略(2)

    Android使用XML全攻略(2)   Android 是针对移动设备的一种新兴的开源操作系统和 SDK.借助它,您可以创建功能强大的移动应用程序.当您的应用程序可以访问 Web 服务时,其吸引力会 ...

  5. Android使用XML全攻略(1)

    Android使用XML全攻略(1)    Android 是针对移动设备的一种新兴的开源操作系统和 SDK.借助它,您可以创建功能强大的移动应用程序.当您的应用程序可以访问 Web 服务时,其吸引力 ...

  6. Android屏幕适配全攻略(最权威的官方适配指导)屏幕尺寸 屏幕分辨率 屏幕像素密度 dpdipdpisppx mdpihdpixdpixxdpi

    Android屏幕适配全攻略(最权威的官方适配指导)原创赵凯强 发布于2015-05-19 11:34:17 阅读数 153734 收藏展开 转载请注明出处:http://blog.csdn.net/ ...

  7. 【收藏】Android屏幕适配全攻略(最权威的Google官方适配指导)

    来源:http://blog.csdn.net/zhaokaiqiang1992 更多:Android AutoLayout全新的适配方式, 堪称适配终结者 Android的屏幕适配一直以来都在折磨着 ...

  8. Android屏幕适配全攻略(最权威的官方适配指导)(转),共大家分享。

    Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的官方文档为基础,全面而深入的讲解了Android屏幕适配的原因.重要概念.解决方案及最佳实践,我相信如果你能认真的学习 ...

  9. Android屏幕适配全攻略(最权威的官方适配指导) (转)

    招聘信息: Cocos2d-X 前端主程 [新浪微博]手机客户端iOS研发工程师 20k-40k iOS 开发工程师 iOS高级开发工程师(中国排名第一的企业级移动互联网云计算公司 和创科技 红圈营销 ...

随机推荐

  1. ie 7/8不支持trim的属性的解决方案

    if(!('trim' in String.prototype)){ String.prototype.trim = function(){ return this.replace(/^[\s\uFE ...

  2. Python的高级特性4:函数式编程

    函数式编程的核心就是把函数当成对象来进行编程. 有两个常用到的方法:map/reduce,filter,其中map和filter是内建方法,而reduce不是,所以需要import相关模块. map接 ...

  3. Tomcat 开启 SSL

    生成keystore /usr/java/default/bin/keytool -genkey -alias tomcat -keyalg RSA -keystore ~/tomcat.keysto ...

  4. Broadmann分区

    来源: http://blog.sina.com.cn/s/blog_60a751620100k2hj.html Brodmann areas Name 中文名 Function 1 Somatose ...

  5. 在C#中将String转换成Enum:

    一:  在C#中将String转换成Enum: object Enum.Parse(System.Type enumType, string value, bool ignoreCase); 所以,我 ...

  6. html中label宽度设置、非替换元素和替换元素

    <label ></label> 单独对label设置一个width:100px的属性石不起作用的,和float:left或者display:inline-block配合的话 ...

  7. BZOJ 1014 【JSOI2008】 火星人prefix

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  8. codevs1910 递归函数

    难度等级:黄金 codevs1910 递归函数 题目描述 Description 对于一个递归函数w(a, b, c). 如果a <= 0 or b <= 0 or c <= 0就返 ...

  9. Vue学习笔记-2

    前言 本文非vue教程,仅为学习vue过程中的个人理解与笔记,有说的不正确的地方欢迎指正讨论 1.computed计算属性函数中不能使用vm变量 在计算属性的函数中,不能使用Vue构造函数返回的vm变 ...

  10. DevExpress中设置PanelControl背景的方法

    首先当然是设置BackColor的颜色,但是设置完之后往往是没有反映的,这就Dev的好处带来的不好,然后我们需要自己定义两个属性 1.设置LookAndFeel下的style为Flat或UtralFl ...