Android的打包签名

系列文章:
Android的反编译和代码混淆
Android的打包签名
Android的多渠道打包

前言

从以下几个方面介绍应用的打包签名

  1. Android打包
  2. 签名
  3. 为什么要签名
  4. Android打包流程
  5. 如何为APK签名
  6. 在代码中得到应用的签名?
  7. 注意
  8. 出现问题及解决

Android打包

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

签名

  1. 在android应用文件(apk)中保存的一个特别字符串
  2. 用来标识不同的应用开发者:开发者A,开发者B
  3. 一个应用开发者开发的多款应用使用同一个签名

就好比是一个人写文章,签名就相当于作者的署名。
如果两个应用都是一个开发者开发的,那么签名就是一样的。
这个开发者,可以是个人,也可以是公司、团体。

为什么要签名

原因1:最简单直接的回答: 系统要求的。

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

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

如果只有包名的概念,那么如果B应用与已经安装的A应用包名一样,那就实现覆盖。不合理!
而事实上是装不上B的,它会提示,存在包名一致,但是签名不一样的。这就不会覆盖。

Android打包流程

image.png

如何为APK签名

用来生成应用的签名文件

  • 默认:debug.keystore

debug签名的应用程序不能在Android Market上架销售,它会强制你使用自己的签名。
不同电脑使用此文件生成的签名不一样。那就意味着如果你换了机器进行apk版本升级,那么将会出现上面那种程序不能覆盖安装的问题。

  • 使用Eclipse:xx.keystore
  • 使用Android Studio:xx.jks

打包使用自己签名的APK(使用Android Studio)
以下步骤实现:

image.png

image.png
image.png
image.png

如果没有key store文件,那就创建一个,如下:


image.png

这里指定一个文件名。注意:在as中,签名文件keystore类型的文件变为jks格式的文件。这里输入的是表明是谁,不适合写一个包名。


image.png
  • 上面的密码是用来访问最上面的path路径文件的密码。而最上面的文件用来生成一个签名字符串。
  • 下面Alias是一个别名。接下来的密码:是用来生成一个签名的时候,还需要的一个密码。与上面的密码可以不一致。
  • 再下面的25,指的是有效期。google应用市场规定应用的有效期不低于25年。还可以改为100年。也就是说100年以后,我们的xxx.jks签名文件就失效了。


    image.png
image.png

指明生成的apk的位置,Build Type:release:发布版 和 debug:测试版。
点击finish,稍等一会


image.png

默认在As工程中bin下生成的apk文件也有签名。只是用到了debug_keystore(测试)的模式。而我们想发布到应用市场的话,那就需要我们自己提供一个签名,不能用默认的了,不合适。如下:


image.png

查看签名文件:


image.png

这是生成的用于生成签名的apk文件的文件。而上面的apk文件里已经包含了签名文件

在代码中得到应用的签名?

public void getSingInfo() {
    try {
        PackageInfo packageInfo = getPackageManager().getPackageInfo(
                "com.atguigu.p2p", 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();
    }
}

注意

  1. 千万不要把xxx.keystore/xxx.jks文件弄丢了
  2. 万一丢了只能重新签名了,用户安装时必须先卸载才能成功安装,应用市场上的排行就会从0开始了。

案例:
公司程序员A写的应用,然后走了。后来来了一个程序员B把应用更新以后,又重新打包发布,使用的签名不一致。那完了。
导致出现更新不了应用的情况。必须把应用卸载了才能重新装。那想象一下,如果一个20万用户的应用,在更新时,发现安装不了。那可能随后就卸载了。或者就不更新了。
另外还影响的是:应用市场有下载量排名,如果重新签名,那就得重头来算。

出现问题及解决

现象:
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]
错误截图:


image.png

解决办法:
resources 标签内增加两个属性即可:

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

以上是根据我的一些理解,做的总结分享,旨在抛砖引玉,希望有更多的志同道合的朋友一起讨论学习,共同进步!

推荐阅读更多精彩内容