Android 打包三种方式实例详解

 Android 打包三种方式实例详解

前言:

现在市场上很多app应用存在于各个不同的渠道,大大小小几百个,当我们想要在发布应用之后统计各个渠道的用户下载量,我们就要进行多渠道打包。

01.应用的打包签名什么是打包?

打包就是根据签名和其他标识生成安装包。

签名是什么?

1.在android应用文件(apk)中保存的一个特别字符串

2.用来标识不同的应用开发者:开发者A,开发者B

3.一个应用开发者开发的多款应用使用同一个签名

就好比是一个人写文章,签名就相当于作者的署名。

如果两个应用都是一个开发者开发的,那么签名就是一样的。

这个开发者,可以是个人,也可以是公司、团体。

为什么要用签名?原因1:最简单直接的回答: 系统要求的。

Android系统要求每一个Android应用程序必须要经过数字签名才能够安装到系统中,也就是说如果一个Android应用程序没有经过数字签名,是没有办法安装到系统中的!

原因2:

不同程序员开发的应用包名可能会相同, 导致一个应用覆盖掉另一个应用。

如果只有包名的概念,那么如果B应用与已经安装的A应用包名一样,那就实现覆盖。不合理!

而事实上是装不上B的,它会提示,存在包名一致,但是签名不一样的。这就不会覆盖。

如何为APK签名?

如何签名就不用说了,这方面的博文数不胜数,相信看这篇文章的你也应该会。

在代码中得到应用的签名?(个人觉得没啥用)

public void getSingInfo() {
  try {
    PackageInfo packageInfo = getPackageManager().getPackageInfo(
        "应用包名", PackageManager.GET_SIGNATURES);
    Signature[] signs = packageInfo.signatures;
    Signature sign = signs[0];
    parseSignature(sign.toByteArray());
  } catch (Exception e) {
    e.printStackTrace();
  }
}
public void parseSignature(byte[] signature) {
  try {
    CertificateFactory certFactory = CertificateFactory
        .getInstance("X.509");
    X509Certificate cert = (X509Certificate) certFactory
        .generateCertificate(new ByteArrayInputStream(signature));
    String pubKey = cert.getPublicKey().toString();
    String signNumber = cert.getSerialNumber().toString();
    Log.e("TAG", "pubKey:" + pubKey);
    Log.e("TAG", "signNumber:" + signNumber);
  } catch (Exception e) {
    e.printStackTrace();
  }
}

注意问题:

现象:

Android导出APK包时出现,编译调试时不会出现。

错误信息:

Error:(16) Error: “baidutieba_client_inavailable” is not translated in “en” (English) [MissingTranslation]
Error:(63) Error: “baidutieba” is not translated in “en” (English) [MissingTranslation]
Error:(67) Error: “share_to_baidutieba” is not translated in “en” (English) [MissingTranslation]

错误截图:

解决办法:

resources 标签内增加两个属性即可:

<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:tools="http://schemas.android.com/tools"
 tools:ignore="MissingTranslation">
</resources>

02.友盟的多渠道打包说明:1.什么是多渠道包?

渠道包就是要在安装包中添加渠道信息,也就是channel,对应不同的渠道,例如:小米市场、360市场、应用宝市场等

2.为什么要提供多渠道包?

我们要在安装包中添加不同的标识,应用在请求网络的时候携带渠道信息,方便后台做运营统计(这就是添加渠道信息的用处)。

3.实现多渠道打包的原理:

一般来讲,这个渠道的标识会放在AndroidManifest.xml的Application的一个Metadata中。然后就可以在java中通过API获取对应的数据了。

4.如何实现?

现在android渠道多种多样,其实渠道不仅仅局限于应用市场,一种推广方式也可以看做一个渠道,比如:通过人拉人的方式去推广,官网上推广,百度推广等。所以说渠道成千上万,为了推广,有时候一次也会打成千的安装包,那你半天或者一天啥都别干了,所以介绍几个大公司高效的打包方式,借鉴一下。

第一种:友盟就提供了多渠道打包的方式,可用于渠道统计等。
现在Android的构建工具换成了gradle,通过gradle,简单配置后就可以实现自动打所有渠道包。

实现步骤:

1.按照umeng的要求,manifest文件中需要有

<meta-data
 android:name="UMENG_CHANNEL"
 android:value="${UMENG_CHANNEL_VALUE}" />

这段配置,value那里就是wandoujia,360之类的渠道名称,但是我们在这里不会去写渠道名,写的是一个占位符,后面gradle编译的时候会动态的替换掉它。

2、在module(一般也就是app)的build.gradle的android{}中添加如下内容:

productFlavors{
     wandoujia{
       manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
     }
     xiaomi{
       manifestPlaceholders=[UMENG_CHANNEL_VALUE: "xiaomi"]
     }
   }

productFlavors是android节点的一个自节点。你需要打什么渠道的包,就在这里按umeng的要求用渠道名给UMENG_CHANNEL_VALUE赋值。

3、优化1:上面只是两个渠道,如果有几十个渠道,都这样写,重复的东西太多,观察到每个渠道就是flavor的名称,所以修改如下:

productFlavors{
 wandoujia{

 }
 xiaomi{

 }
 }
 productFlavors.all { flavor ->
 flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
 }

4、优化2:上面经过签名打包后生成的apk的名称是有默认命名规则的,如:xxx-xiaomi-release.apk 但是我们想包含版本信息如:xxx-xiaomi-release-1.0.apk,所以最终打包脚本如下:

productFlavors{
  wandoujia{

  }
  xiaomi{

  }
 }
 productFlavors.all { flavor ->
  flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
 }
 applicationVariants.all { variant ->
  variant.outputs.each { output ->
    def outputFile = output.outputFile
    if (outputFile != null && outputFile.name.endsWith('.apk')) {
      def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
      output.outputFile = new File(outputFile.parent, fileName)
    }
  }
 }

4.获取渠道

在代码中我们可以通过读取mate-data信息来获取渠道,然后添加到请求参数中,获取方法如下:

private String getChannel() {
  try {
    PackageManager pm = getPackageManager();
    ApplicationInfo appInfo = pm.getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
    return appInfo.metaData.getString("UMENG_CHANNEL");
  } catch (PackageManager.NameNotFoundException ignored) {
  }
  return "";
}

5、执行签名打包

这时候你去app/build/outputs/apk中就能看到自动打好的渠道包了。

6、缺点:

这样的打包方式效率比较低下,如果是几十个包还可以应付,打一个包快的话需要十几秒,慢的话需要几分钟不等,跟机器性能很有关系。

03、美团多渠道打包原理:

把一个Android应用包当作zip文件包进行解压,然后发现在签名生成的目录下(META-INF)添加一个空文件不需要重新签名。利用这个机制,该文件的文件名就是渠道名。这种方式不需要重新签名等步骤,非常高效,但是貌似在Android7.0之后,Google为了增强签名的安全性,采用了新的签名规则,不是针对每个文件来进行数字编码,而是对zip包文件结构编码签名后产生一个唯一的数据叫做apk signing block。如果修改了zip文件的任何模块的内容,APK Signing Block都会发生改变,从而无法再绕过签名机制。

方法:

首先你需要去下载相关的工具:

详细步骤:

1、将要打包的apk放到PythonTool中
2、在PythonTool/info/channel.txt中写入需要的渠道,一个渠道占一行
3、双击执行PythonTool/MultiChannelBuildTool.py文件(需要Python环境),就会生成渠道包
4、获取渠道信息:将JavaUtil文件中的ChannelUtil.java拷贝到工程,调用ChannelUtil.getChannel即可获取渠道.

优缺点:

优点:

这种打包方式速度非常快,900多个渠道不到一分钟就能打完

缺点:

1、google现在已经修改了新的签名规则,若使用新的签名规则则无法使用(老的无所谓)。

2、一些不法的渠道商很容易通过工具修改渠道,如果一个渠道商,通过网络劫持和篡改渠道的组合方式来获取暴利,对于程序开发者来说可能会存在着巨大的经济损失

04、360多渠道打包:

apk文件本质就是zip文件,利用zip文件“可以添加comment(摘要)”的数据结构特点,在文件的末尾写入任意数据,而不用重新解压zip文件,我们就可以将渠道信息写入摘要区

方法:

首先还是去下载相关工具:

步骤:

1、将要写入渠道信息的apk放入MCPTool文件夹中
2、修改MCPTool.bat批处理文件,更改渠道和密码(渠道信息为了安全需要加密)

3、将apk拖到MCPTool.bat上执行,将会生成渠道包

4、修改MCPTool-check.bat中的密码和MCPTool.bat中的密码一致

5、将渠道包拖到MCPTool-check.bat上执行,就可以检查渠道信息是否正确

6、获取渠道:将MCPTool.java添加到工程或者将MCPTool.jar导入工程,调用 MCPTool.getChannelId(this,”12345678”,”“) 第一个参数为context,第二个是密码,第三个是默认值。

优缺点:

优点:

1、5M的apk,1秒种能打300个
2、在下载apk的同时,服务端可以写入一些信息,例如邀请码,分享信息等

缺点:

渠道信息也是很容易修改,虽然可以加密,只是提高了修改的门槛

以上就是多渠道打包的一些方法,目前大部分公司常用的还是友盟的打包方式。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2017-04-27

怎么发布打包并发布自己的Android应用(APP)

第一步,在Eclipse中选择需要打包的项目,然后右键--选择Export,会弹出一个打包的提示框,如下图所示. 按Next之后,会继续出现一个提示框,这里你可以选择自己需要打包的项目(默认是刚才选中的)如下图: 按Next之后,会弹出一个关于"Keystore"的提示,选择"Create new Keystore",并浏览.选择签名文件要保存的路径, (关于Keystore的原理.作用等这里暂时不细说,请大家发布前务必保存好该签名文件,非常重要的.) 如下图所示:

Gradle编译打包Android apk详细介绍

Gradle编译打包Android apk详细介绍 理解Gradle构建过程,解读Android Gradle插件的配置 阅读本文一定是要使用过Gradle生成apk,文中不会讲如何安装运行Gradle,如有需要可先看文末的参考文章. APK包是一个ZIP压缩包,从Java源代码.资源文件到生成这个APK,经过了编译打包一系列特定的过程,SDK文档(/docs/tools/building/index.html)中找到.而这一系列特定的过程,重复繁琐,构建工具(build tool)就是来流程化

Android客户端程序Gradle如何打包

一.前言 android客户端开发进入尾声,负责SEO同事突然发给我一个涉及45个发布渠道的噩耗,之前只发布自有渠道的工作方式(手动修改参数打包)已经不满足需求,所以引入最近比较流行的gradle打包技术. gradle基于groovy语言,引入的原因也方便了以后从现在使用的eclipse开发环境迁移到Android Studio,所以blablabla--,不多说了,先上干货. 二.准备工作 1.首先,如果使用eclipse作为开发环境,需右键点击项目,在菜单中选择"Export-"

Android应用程序(APK)的编译打包过程

流程图: 我们重点关心的是(1)这个过程的输入是什么?(2)这个过程的输出是什么?(3)这个过程使用了什么工具?至于使用什么参数,可以自己去看对应命令的帮助文件,或者在网上搜索,这不是本文的重点. aapt-> aidl -> javac-> dx(dex)-> apkbuilder-> jarsigner-> zipalign  步骤中提到的工具如下表: 名称 功能介绍 在操作系统中的路径 aapt Android资源打包工具 ${ANDROID_SDK_HOME}/

ANDROID应用程序的混淆打包分享

android应用程序的混淆打包1 . 在工程文件project.properties中加入下proguard.config=proguard.cfg , 如下所示:target=android-8 proguard.config=proguard.cfg Eclipse会通过此配置在工程目录生成proguard.cfg文件 2 . 生成keystore (如已有可直接利用) 按照下面的命令行 在D:\Program Files\Java\jdk1.6.0_07\bin>目录下,输入keytoo

Android studio 混淆+打包+验证是否成功

前言: 单挑Android项目,最近即时通讯用到环信,集成sdk的时候 官方有一句 在 ProGuard 文件中加入以下 keep. -keep class com.hyphenate.** {*;} -dontwarn com.hyphenate.** 即:混淆规则. 自己没写过关于混淆打包的文章,在此补上. 下面了解Android studio环境下 项目混淆打包的操作. 一.打包: 即 将Android项目生成.apk文件,让用户去安装. 1.工具栏 Build->Generate Sig

Android Studio 超级简单的打包生成apk的方法

本文介绍了Android Studio 超级简单的打包生成apk,分享给大家,也给自己留个笔记. 为什么要打包: apk文件就是一个包,打包就是要生成apk文件,有了apk别人才能安装使用.打包分debug版和release包,通常所说的打包指生成release版的apk,release版的apk会比debug版的小,release版的还会进行混淆和用自己的keystore签名,以防止别人反编译后重新打包替换你的应用. 简单点说就是给你的apk发身份证,上户口,防止和你长的一样的人,假冒你.这里

android studio 3.0 gradle 打包脚本配置详解

本文介绍了android studio 3.0 gradle 打包脚本配置,分享给大家,具体如下: 修改输出的名字 保存输出的文件路径 def fileArray = [] //遍历输出文件 android.applicationVariants.all { variant -> variant.outputs.all { output -> def outputFile = output.outputFile if (outputFile != null && outputF

Android studio 下的APK打包失败问题解决办法

Android studio 下的APK打包失败问题解决办法 今天遇到了一个奇怪的问题,本来在Android studio 1.4上运行的好好的程序,到了我更新完的Android studio 2.1上就打包失败了,但是用调试机直接运行则没问题. 最后在app下的build.gradle下加入了这样的一段代码就通过了: lintOptions { abortOnError false checkReleaseBuilds false // 防止在发布的时候出现因MissingTranslatio

Android应用程序更新并下载实例

整理文档,搜刮出一个Android应用程序更新并下载实例的代码,稍微整理精简一下做下分享. 创建一个新类,名为UpdateManager,代码如下: import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader;

Android判断程序是否第一次启动

本文实例为大家分享了Android判断程序是否第一次启动的具体代码,供大家参考,具体内容如下 public class Welcome extends Activity { private final long SPLASH_LENGTH = 2000; Handler handler = new Handler(); public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); set

Android应用程序模型之应用程序,任务,进程,线程分析

本文讲述了Android应用程序模型之应用程序,任务,进程,线程.分享给大家供大家参考,具体如下: 大多数操作系统,在应用程序所寄存的可执行程序映像(如Windows系统里的.exe).它所运行的进程以及和用户交互的图标和应用之间有一种严格的1对1关系.在Android系统里,这些关联要松散得多.并且重要的是要理解各种概念怎么样组成整体. 由于Android应用固有的灵活性,当实现这些不同方面的时候有一些基本术语需要加以理解: ① 一个Android包 (.apk)文件,其中包含一个应用程序的代

Android 在程序运行时申请权限的实例讲解

这里我们以拨打电话申请权限来写个小例子,也就是CALL_PHONE,因为拨打电话会涉及用户手机的资费问题,因而被列为了危险权限,在Android6.0系统出现之前,拨打电话功能的实现其实非常简单,修改activity_mainxml中的代码,如下: <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android=&qu