我们使用Android Studio 运行我们的app,无非两种模式:debug和release模式。

debug模式

debug模式使用一个默认的debug.keystore进行签名。

这个默认签名(keystore)是不需要密码的,它的默认位置在C:\Users\<用户名>\.Android\debug.keystore,如果不存在Android studio会自动创建它。

例如我的debug.keystore就在C:\Users\Administrator\.android\debug.keystore。

 

release模式

在我们正式发布项目的时候是不能使用debug.keystore的。开发过程中我们也可以使用发布模式运行。可以通过如下设置:

BuildVariants-Build Variant-debug/release

如果项目需要细分开发dev和生产pro版本,每个版本中都包含debug和release模式,可以这么设置:

就细分成四种模式:

release模式需要配置签名才能运行,这时就需要一个keystore

如果没有就需要创建,已经创建过keystore请跳过此步骤

 

1.创建keystore,并生成我们的apk(打包)

 第一步: Build --->> Generate Signed APK

第二步:Create New···(已经创建过keystore选Choose existing···)

第三步:填写相关信息

设置keystore路径、密码,设置key:别名、密码、有效期,证书等

Key store path:存放路径

Key

  Alias:别名

  Validity(years):有效期(一般默认25年)

  Certificate:证书

    First and Last Name:姓名

    Organization Unit:组织单位

    Organization:组织

    City or Locality:城市或地区

    State or Province:州或省

    Country Code(XX):国家代码(XX),中国:86

 

第四步:输入key、keystore密码

第五步:选择发布app的路径,默认即可 选择release方式发布,V1必须勾选!!

OK,发布成功,可以到 刚才设置的目标文件夹下面找到发布的apk

 

那对一些人来说,这样也太麻烦了,每次都得输入相关信息,还得进行选择,那么有更简单快捷的方法吗?答案是有的。

我们可以在项目的app目录下的build.gradle中进行签名的配置。 

2.release模式配置keystore

Project structure-signing,输入已创建的keystore信息

使得签名生效需配置Build Types

点击OK即可,然后查看对应build.gradle的配置文件应该是这样的。当然了,你也可以通过直接在build.gradle里面写下面这段。

signingConfigs {        release {            keyAlias 'androiddebugkey'            keyPassword 'android'            storeFile file('C:/Users/ssc/.android/debug.keystore')            storePassword 'android'        }    }    ·········buildTypes {        release {              //是否混淆            minifyEnabled true              //是否移除无用资源            zipAlignEnabled true              //混淆的配置文件            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'            signingConfig signingConfigs.release        }}

上述的配置虽然配置简单,但是存在不安全性,假如你的项目是开源的,你把签名文件的配置密码之类的信息用明文写在build.gradle里面,那是不是很不安全呢?

可以将签名文件的配置密码之类的信息直接写在local.properties下,因为在Git版本控制的项目中,我们可以看到我们项目project模式根目录下有一个.gitignore的文件,里面的配置大概如下所示

我们可以看到/local.properties,意思就是说local.properties默认是不添加到版本控制里面的,因为local.properties存储的是我们环境资源的一些相关信息,如sdk的路径。故我们可以在local.properties下配置签名信息而不用担心密钥外泄。对于开源项目来说,是非常好的。

在local.properties下直接添加相关信息

在build.gradle里,为了不用明文显示,我们首先要获得key的相关配置,所以我们可以在app的build.gradle里

android {}之上新增代码
def keystoreFilepath = ''def keystorePSW = ''def keystoreAlias = ''def keystoreAliasPSW = ''// default keystore file, PLZ config file path in local.propertiesdef keyfile = file('s.keystore.temp')Properties properties = new Properties()// local.properties file in the root directorproperties.load(project.rootProject.file('local.properties').newDataInputStream())keystoreFilepath = properties.getProperty("keystore.path")if (keystoreFilepath) {    keystorePSW = properties.getProperty("keystore.password")    keystoreAlias = properties.getProperty("keystore.alias")    keystoreAliasPSW = properties.getProperty("keystore.alias_password")    keyfile = file(keystoreFilepath)}

app/build.gradle下的signingConfigs可以改为:

1

2

3

4

5

6

7

8

signingConfigs {

       release {

           keyAlias keystoreAlias

           keyPassword keystoreAliasPSW

           storeFile keyfile

           storePassword keystorePSW

       }

   }

  

设置后Signing中keystore值无需关心

相应的,buildTypes也可以配置成这样

buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//            signingConfig signingConfigs.release            //签名文件存在,则签名            if (keyfile.exists()) {                println("WITH -> buildTypes -> release: using jks key")                signingConfig signingConfigs.release            } else {                println("WITH -> buildTypes -> release: using default key")            }            23       }    }

到此,前面配置完成。

 部分内容转载自:http://www.cnblogs.com/details-666/p/keystore.html并进行更新。

附:查询keystore的相关信息,如查看sha1的值;可以在运行窗口,定位到keystore所在的路径,执行cd C:\Users\ssc\.android

执行这条语句后就能显示Key的所有信息(以android默认keystore为例)

keytool -list -v -keystore xxx.jks 

 

Android studio(windows平台上)更新到2.3版本以后,在没有充分了解它的新变化的情况下,使用的时候难免会遇到一些问题,比如gradle的问题可能是大家最常见的,不过解决的一般思路和之前(例如2.1更新到2.2之类的)没太大区别,本文要说不是gradle的问题,而是给apk正式签名后安装失败的问题。

附录:

签名打包遇到问题

1.

项目在正式上线之前一般都要有正式签名,也就是发布release版本的apk,而不再使用默认的debug版签名文件----debug.keystore。最常用的方式就是通过Android studio的工具栏里的Build-->Generate Signed APK...方式去签名。更多的步骤不再赘述,按照提示一步步的往下走就可以,相信大家都知道了。

这种方式签名后的apk就是发布版(release)的apk,android studio2.3之前是可以直接安装到设备上的,安装方式之一就是在docs命令行里用adb install 命令去安装到连接到PC上的Android设备。但是,Android studio2.3以后这种方式打包apk的话就有了些变化:

就如画圈的地方,2.3以前应该是没有的(印象中是没有,如果有的话是我记错了,见谅),多了这些选项的话不选择是无法继续下去的,选择的话,我当时看到V2和apk有关,V1和jar有关,在没有弄明白区别的时候果断选择V2的方式,然后点击了Finish.等了一会,apk打包好了,我用adb install命令安装这个apk的时候却遇到这样的问题:

对,就是说没有签名证书!但是我确实是签了名了啊,而且相应的.jks文件也是存在的。我通过手动编辑gradle文件进行签名的话再安装也是OK的。于是我clean,rebuild,新建项目,重启studio...各种方式都试了,然后通过这种方式签名打包后的apk仍然存在这个问题。于是只能上网找答案,然后就发现了问题确实是在上述画圈的地方:把V1单独勾选或者V1和V2都勾选的话,再打包就是OK的,也就是说只要勾选了V1就行,生成的apk就可以正常安装...晕。

2.升级完Android Studio2.3后,打包release出现的错误

Error:Execution failed for task ':qq:lintVitalRelease'.
> Lint found fatal errors while assembling a release target.
To proceed, either fix the issues identified by lint, or modify your build script as follows:
...
android {
    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }
}
...


解决方法:
在app的build.gradle中添加如下代码,重新Generate Signed APK即可

android{    lintOptions {        checkReleaseBuilds false        abortOnError false    }}

 

安卓混淆

build.gradle文件:

buildTypes {        release {            minifyEnabled true            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'                  }            }

混淆文件proguard-rules.pro:

-optimizationpasses 7  #指定代码的压缩级别 0 - 7-dontusemixedcaseclassnames  #是否使用大小写混合-dontskipnonpubliclibraryclasses  #如果应用程序引入的有jar包,并且想混淆jar包里面的class-dontpreverify  #混淆时是否做预校验(可去掉加快混淆速度)-verbose #混淆时是否记录日志(混淆后生产映射文件 map 类名 -> 转化后类名的映射-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*  #淆采用的算法-ignorewarnings #屏蔽警告-keep public class * extends android.app.Activity  #所有activity的子类不要去混淆-keep public class * extends android.app.Application-keep public class * extends android.app.Service-keep public class * extends android.content.BroadcastReceiver-keep public class * extends android.content.ContentProvider-keep public class * extends android.app.backup.BackupAgentHelper-keep public class * extends android.preference.Preference-keep public class com.android.vending.licensing.ILicensingService #指定具体类不要去混淆-keepclasseswithmembernames class * {    native ;  #保持 native 的方法不去混淆}-keepclasseswithmembers class * {    public (android.content.Context, android.util.AttributeSet);  #保持自定义控件类不被混淆,指定格式的构造方法不去混淆}-keepclasseswithmembers class * {    public (android.content.Context, android.util.AttributeSet, int);}-keepclassmembers class * extends android.app.Activity {    public void *(android.view.View); #保持指定规则的方法不被混淆(Android layout 布局文件中为控件配置的onClick方法不能混淆)}-keep public class * extends android.view.View {  #保持自定义控件指定规则的方法不被混淆    public (android.content.Context);    public (android.content.Context, android.util.AttributeSet);    public (android.content.Context, android.util.AttributeSet, int);    public void set*(...);}-keepclassmembers enum * {  #保持枚举 enum 不被混淆    public static **[] values();    public static ** valueOf(java.lang.String);}-keep class * implements android.os.Parcelable {  #保持 Parcelable 不被混淆(aidl文件不能去混淆)    public static final android.os.Parcelable$Creator *;}-keepnames class * implements java.io.Serializable #需要序列化和反序列化的类不能被混淆(注:Java反射用到的类也不能被混淆)-keepclassmembers class * implements java.io.Serializable { #保护实现接口Serializable的类中,指定规则的类成员不被混淆    static final long serialVersionUID;    private static final java.io.ObjectStreamField[] serialPersistentFields;    !static !transient ;    private void writeObject(java.io.ObjectOutputStream);    private void readObject(java.io.ObjectInputStream);    java.lang.Object writeReplace();    java.lang.Object readResolve();}-keepattributes Signature  #过滤泛型(不写可能会出现类型转换错误,一般情况把这个加上就是了)-keepattributes *Annotation*  #假如项目中有用到注解,应加入这行配置-keep class **.R$* { *; }  #保持R文件不被混淆,否则,你的反射是获取不到资源id的-keep class **.Webview2JsInterface { *; }  #保护WebView对HTML页面的API不被混淆-keepclassmembers class * extends android.webkit.WebViewClient {  #如果你的项目中用到了webview的复杂操作 ,最好加入     public void *(android.webkit.WebView,java.lang.String,android.graphics.Bitmap);     public boolean *(android.webkit.WebView,java.lang.String);}-keepclassmembers class * extends android.webkit.WebChromeClient {  #如果你的项目中用到了webview的复杂操作 ,最好加入     public void *(android.webkit.WebView,java.lang.String);}#对WebView的简单说明下:经过实战检验,做腾讯QQ登录,如果引用他们提供的jar,若不加防止WebChromeClient混淆的代码,oauth认证无法回调,反编译基代码后可看到他们有用到WebChromeClient,加入此代码即可。-keepclassmembernames class com.cgv.cn.movie.common.bean.** { *; }  #转换JSON的JavaBean,类成员名称保护,使其不被混淆################################################################### 下面都是项目中引入的第三方 jar 包。第三方 jar 包中的代码不是我们的目标和关心的对象,故而对此我们全部忽略不进行混淆。##################################################################  #-libraryjars /libs/android-support-v4.jar -dontwarn android.support.v4.** -keep class android.support.v4.** { *; } -keep public class * extends android.support.v4.** -keep public class * extends android.app.Fragment #-libraryjars /libs/pdf.jar-dontwarn com.neusoft.android.pdf.**-dontwarn com.example.pdfactivity04.**-keep class com.neusoft.android.pdf.** { *;}-keep class com.example.pdfactivity04.** { *;}-dontwarn com.itextpdf.**-dontwarn org.apache.**-keep class com.itextpdf.**{*;}-keep class org.apache.**{*;}-dontwarn com.google.**-keep class com.google.**{*;}-dontwarn com.tencent.**-keep class com.tencent.**{*;}-dontwarn com.lidroid.**-keep class com.lidroid.**{*;}-keep class com.duicky.TestProvider{*;}#-dontwarn com.ui.**#-keep class com.ui.**{*;}#-dontwarn com.turui.**#-keep class com.turui.**{*;}#-dontwarn com.idcard.**#-keep class com.idcard.**{*;}-dontwarn com.i2trust.**-keep class com.i2trust.**{*;}-dontwarn com.hisign.**-keep class com.hisign.**{*;}-dontwarn com.ccit.**-keep class com.ccit.**{*;}-dontwarn com.plk.bluetoothlesdk.**-keep class com.plk.bluetoothlesdk.**{*;}-dontwarn org.kobjects.**-keep class org.kobjects.**{*;}-dontwarn org.ksoap2.**-keep class org.ksoap2.**{*;}-dontwarn org.kxml2.**-keep class org.kxml2.**{*;}-dontwarn org.xmlpull.**-keep class org.xmlpull.**{*;}-dontwarn org.nanohttpd.**-keep class org.nanohttpd.**{*;}-dontwarn com.sensetime.senseid.sdk.**-keep class com.sensetime.senseid.sdk.**{*;}#-libraryjars /libs/commons-codec-1.3.jar#-libraryjars /libs/commons-httpclient-3.1.jar#-libraryjars /libs/commons-logging-1.1.jar#-libraryjars /libs/zxing.jar#-libraryjars /libs/httpclient-4.3.6.jar#-libraryjars /libs/httpcore-4.3.2.jar#-libraryjars /libs/httpmime-4.3.5.jar#-libraryjars /libs/itextpdf.jar#-libraryjars /libs/libammsdk.jar#-libraryjars /libs/xUtils-2.6.14.jar#-libraryjars /libs/livedetectCTID.jar#-libraryjars /libs/i2trustauthensdk.jar#-libraryjars /libs/plkbluetoothlesdk.jar#-libraryjars /libs/ldap.jar#-libraryjars /libs/ksoap2-android-assembly-3.6.0-jar-with-dependencies.jar#-libraryjars /libs/MKeySDK.jar

更多相关文章

  1. 转载:Android中如何修改系统时间(应用程序获得系统权限)
  2. android 5.1.1开机优化(framework层)
  3. Unity头像上传功能实现 二
  4. Android(安卓)美化之Toolbar控件使用
  5. 安装Android(安卓)2.2 SDK时出现的问题
  6. Android(安卓)adb push ... Read-only file system
  7. android创建文件夹和文件
  8. AndroidStudio使用GreenDao实战
  9. Android对文件的操作(简单的文件读取与写入)

随机推荐

  1. 没事抽空学——常用界面组件属性
  2. android 呼出电话的监听(去电监听)
  3. Android(安卓)Studio安装完后,遇到了sdk m
  4. Android(安卓)第一次启动时预安装apk
  5. Android中listview中的button
  6. Android(安卓)Material Design: Navigati
  7. Android中listview中的button
  8. 《Android传感器高级编程》
  9. 请介绍下Android中常用的五种布局
  10. android应用安全——通信安全(android htt