前言

搞安卓的开发应该知道开发好的apk都是需要上传到应用市场给用户下载的,当然有些公司的产品是不用上传到应用市场的(比如我们公司放七牛云)但是也需要放在云上面给用户下载。react-native直接run-android默认是产生一个debug的版本apk显然这是不符合开发需求的,理由很简单debug版本apk是没有进行代码混淆的这是很危险的,所以我们需要个release的版本,下面我们来详细看一下怎么样进行签名打包React Native应用并且多渠道打包。

debug和release版本apk反编译后比较

准备工具

先下载反编译工具包:dex2jar-2.0、jd-gui、apktool

反编译

先把apk解压获取classes.dex,再获得classes-dex2jar.jar

使用jd-gui查看源代码(debug版本效果)

当然这里只是helloword做个例子,并没有写什么代码即使混淆了也看不出什么效果(因为第三方的包都不能混淆),但是混淆后效果还是好点:看下其他的例子(直接偷郭霖的图):(release版本效果)

Android签名文件生成

Android签名文件包含2种格式:.keystore和.jks

安卓签名文件的生成不外乎2种方式:我现在给大家讲解两种签名生成的方法:①:keytool命令方式生成 ,②:Android Studio IDE和Eclipse IDE进行生成。

  • keytool命令生成keystore文件(如果没有安装androidStudio或eclispe)

以前我也有写过用蓝贝儿多渠道打包里面介绍了使用自带的keytool命令生成签名文件,这里再来介绍一下

keytool -genkey -v -keystore losileeya.keystore -alias losileeya(别名) -keyalg RSA(算法) -keysize 2048(密钥长度) -validity 10000(有效期,天单位)

个人比较倾向于使用ide这一种方法,首先是图形界面的,而且少了命令行书写的问题,而且以前我记得在使用Eclipse开发Android的时候也一直使用这种方式,下面我们来看一下生成签名的具体步骤:

  • IDE 工具生成签名文件

    1.Android Studio IDE生成jks文件

    build—>Generate Signed apk

    接下来:

    2.Eclipse IDE生成keystore文件

Gradle配置

(1)把刚才生成的.jks文件考入到项目android/app文件夹下面

(2)直接在工程目录下得android/app/build.gradle中以下节点添加如下内容:
方法一:gradle的全局配置:
修改项目中gradle.properties文件

MYAPP_RELEASE_STORE_FILE=losileeya.jks
MYAPP_RELEASE_KEY_ALIAS=losileeya
MYAPP_RELEASE_STORE_PASSWORD=losileeya
MYAPP_RELEASE_KEY_PASSWORD=losileeya

直接在工程目录下得android/app/build.gradle中以下节点添加如下内容:

 signingConfigs {release {storeFile file(MYAPP_RELEASE_STORE_FILE)storePassword MYAPP_RELEASE_STORE_PASSWORDkeyAlias MYAPP_RELEASE_KEY_ALIASkeyPassword MYAPP_RELEASE_KEY_PASSWORD}}buildTypes {release {...signingConfig signingConfigs.release}}

方法二:gradle的局部配置:

  signingConfigs {release {storeFile file("C://Users/Administrator/ZyReact/android/app/losileeya.jks")//这里可以写绝对位置或者相对位置storePassword "losileeya"keyAlias "losileeya"keyPassword "losileeya"}}buildTypes {release {minifyEnabled enableProguardInReleaseBuildsproguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"signingConfig signingConfigs.release}}

看图:

记得把enableProguardInReleaseBuilds改为true,最好把enableSeparateBuildPerCPUArchitecture = true,然后各种签名参数的值都不能错否则打包失败,基本上build.gradle的配置也就这些了。当然代码混淆文件proguard-rules.pro自己配置。
例如我上个项目:

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
# 指定代码的压缩级别0~7
-optimizationpasses 5
# 是否使用大小写混合
-dontusemixedcaseclassnames
# 是否混淆第三方jar
-dontskipnonpubliclibraryclasses
# 混淆时是否做预校验
-dontpreverify
#重命名
-renamesourcefileattribute SourceFile
#保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-keepattributes SourceFile,LineNumberTable
# 混淆时是否记录日志
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
##压缩 #不压缩输入的类文件
-dontshrink
##优化
#不优化输入的类文件
-dontoptimize
#优化时允许访问并修改有修饰符的类和类的成员
-allowaccessmodification
#混淆库
-libraryjars libs/volley.jar
-libraryjars libs/android-support-v4.jar
-libraryjars libs/gson-2.3.1.jar
-libraryjars libs/locSDK_6.13.jar
-libraryjars libs/zxing-core-3.1.0.jar
#-libraryjars libs/MarsorUtils-1.0.0-SNAPSHOT.jar
-libraryjars libs/dom4j-2.0.0-RC1.jar
-libraryjars libs/mta-sdk-1.6.2.jar
-libraryjars libs/open_sdk_r5509.jar
-libraryjars libs/libammsdk.jar
-libraryjars libs/WeiboSDKCore_3.1.2.jar
-libraryjars libs/alipaySDK-20150724.jar
-libraryjars libs/CMISUBTSwiper_sdk_v1.3.jar
-libraryjars libs/CMSETSwiper_SDK_V3.6.jar
-libraryjars libs/dspread_android_sdk_2.4.6.jar
-libraryjars libs/message_lib.jar
-libraryjars libs/meSdk-1.1.7snapshot_ruiyin.jar
-libraryjars libs/disklrucache-2.0.1.jar
-libraryjars libs/httpclient-4.2.5.jar
-libraryjars libs/httpcore-4.2.4.jar
-libraryjars libs/universal-image-loader-1.9.5.jar
-keepattributes *Annotation*
-keep class android.** {*; }
-keep public class * extends android.view
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.pm
-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 * extends android.app.Fragment
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.v4.app.** { *; }
-keep class android.support.v7.** { *; }
-keep class com.google.gson.** { *; }
-keep class com.baidu.mapapi.** { *; }
-keep class com.baidu.platform.** { *; }
-keep class com.baidu.vi.** { *; }
-keep class com.baidu.location.** { *; }
-keep class org.apache.http.** { *; }
-keep class org.json.** { *; }
-keep class com.nostra13.universalimageloader.** { *; }
# keep 所有的 javabean
-keep class com.richerpay.ryshop.bean.** { *; }
# volley
# # -------------------------------------------
# #  ############### volley混淆  ###############
# # -------------------------------------------
-keep class com.android.volley.** {*;}
-keep class com.android.volley.toolbox.** {*;}
-keep class com.android.volley.Response$* { *; }
-keep class com.android.volley.Request$* { *; }
-keep class com.android.volley.RequestQueue$* { *; }
-keep class com.android.volley.toolbox.HurlStack$* { *; }
-keep class com.android.volley.toolbox.ImageLoader$* { *; }
-keep class org.dom4j.** { *; }
-keep class android.support.annotation.** { *; }
-keep class com.tencent.mm.sdk.** {*;}
-keep class com.tencent.tauth.** {*;}
-keep class com.tencent.open.TDialog$*
-keep class com.tencent.open.TDialog$* {*;}
-keep class com.tencent.open.PKDialog
-keep class com.tencent.open.PKDialog {*;}
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
-keep class com.misu.btswiper.**{*;}
-keep class com.shxy.cardswiper.**{*;}
-keep class com.dspread.xpos.QPOSService.**{*;}
-keep class com.bypay.swiper.**{*;}
-keep class com.newland.ruiyin.**{*;}
# 保持自己定义的类不被混淆
-keep class com.richerpay.ryshop.view.**{*;}
-keep class com.richerpay.ryshop.volly.**{*;}
-keep class com.richerpay.ryshop.widget.**{*;}
-dontwarn org.apache.http.**
-keepclassmembers class * {   public <init>(org.json.JSONObject);
}
-keep public class com.hrbcb.studentloans.R$*{public static final int *;
}
# 微信
-keep class com.tencent.mm.sdk.openapi.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.openapi.** implements com.tencent.mm.sdk.openapi.WXMediaMessage$IMediaObject {*;}
# 新浪微博
-keep class com.sina.**{*;}
#枚举不被混淆
-keepclassmembers enum * {
    public static **[] values();public static ** valueOf(java.lang.String);
}
# 保持自定义控件类不被混淆
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {    public <init>(android.content.Context, android.util.AttributeSet, int);
}
#点击事件不被混淆
-keepclasseswithmembers class * {    void onClick*(...);
}
#回调
-keepclasseswithmembers class * {    *** *Callback(...);
}
#get 和set
-keepclassmembers public class * extends android.view.View {   void set*(***);*** get*();
}#本地方法
-keepclasseswithmembernames class * {    native <methods>;
}
# activity
-keepclassmembers class * extends android.app.Activity {   public void *(android.view.View);
}
#实现Parcelable 接口的不被混淆
-keep class * implements android.os.Parcelable {  public static final android.os.Parcelable$Creator *;
}
#R文件属性不被混淆
-keepclassmembers class **.R$* {    public static <fields>;
}#缺省proguard 会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。
-dontwarn android.support.**
# 实现Serializable 接口的不被混淆
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {    static final long serialVersionUID;private static final java.io.ObjectStreamField[] serialPersistentFields;private void writeObject(java.io.ObjectOutputStream);private void readObject(java.io.ObjectInputStream);java.lang.Object writeReplace();java.lang.Object readResolve();public <fields>;
}#dom4j不被混淆
-keepclassmembers class org.dom4j.** {*;}
#百度定位
-keepclassmembers class com.baidu.location.** {*;}
-keepattributes Signature

# Gson混淆
## ----------------------------------
##   ########## Gson混淆    ##########
## ----------------------------------
-keepclassmembers class com.google.gson.** {*;}
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
# Application classes that will be serialized/deserialized over Gson##---------------End: proguard configuration for Gson  ----------
-ignorewarnings
-dontwarn org.xmlpull.v1.XmlSerializer
-keepattributes Signature  

这个只是规则可以参考下,毕竟react-native没有什么activity这写东西,如果你对这个还是不了解,可以去看郭神的反编译与混淆技术完全解析(下)

打包文件的生成2种方式

对存在react.gradle文件的项目打包

命令很简单:

cd android && ./gradle assembleRelease


网速渣的一逼:5min

不存在react.gradle文件的项目打包

对不存在react.gradle文件那么我们就需要生成assets文件夹,并且生成index.android.bundle文件

方法一:利用curl生成
命令如下:

cd ZyReact(定位到你的工程根目录)
curl -k "http//localhost:8081/index.android.bundle" >android/app/src/main/assets/index.android.bundle

如图:

这里使用的curl.exe要自己去下载,记得需要开启服务。生成成功后如下:

方法二:
首先命令切换到该react native项目的主目录,然后运行以下的命令,生成assets文件夹

mkdir -p android/app/src/main/assets

紧接着运行以下命令,进行生成index.android.bundle文件

react-native bundle --platform android --dev false --entry-file index.android.js \--bundle-output android/app/src/main/assets/index.android.bundle \--assets-dest android/app/src/main/res/

总之不管哪种方法打包都要执行

cd android && ./gradle assembleRelease

下面我们来看一下release包的效果:

安装apk

上面的步骤我们已经完成了项目的签名打包在对应的目录中生成中apk文件,下面我们直接运行以下的命令进行将apk安装到设备中。

cd android && ./gradle installRelease

看图:

美团多渠道极速打包

为什么要进行多渠道打包?

不搞安卓开发的或许不知道什么是多渠道打包,ios呢也就一般放appstore里面,然而打包安卓应用商店(一个商店也叫做一个渠道,如360,baidu,xiaomi,应用宝)众多,大大小小几百个,我们发布应用之后需要统计各个渠道的用户下载量,所以才有了多渠道打包。

怎么样统计各个渠道的下载量呢?

现在有比较成熟的第三方应用帮我们实现统计功能(比如友盟),统计的本质就是收集用户信息传输到后台,后台生成报表,帮助我们跟踪分析并完善app。通过系统的方法已经可以获取到,版本号,版本名称,系统版本,机型,地区等各种信息,唯独应用商店(渠道)的信息我们是没有办法从系统获取到的,所以我们就人为的在apk里面添加渠道信息(其实就用一个字段进行标识,如360,baidu),我们只要把这些信息打包到apk文件并将信息传输到后台,后台根据这个标识,可以统计各个渠道的下载量了,并没有多么的高大上。
说了那么多,其实多渠道打包只需要关注两件事情:

1.将渠道信息写入apk文件

2.将apk中的渠道信息传输到统计后台

常见的多渠道打包方法有哪些?

1.插件打包法
2.Android的productFlavors打包法

以前我也写过多渠道比如蓝贝壳多渠道(插件打包法)打包,但是呢速度还是比较慢,然后也写过android studio的多渠道打包(Android的productFlavors打包法)需要手动去配置然后速度也不是很快,然后美团的打包方式以快著称,哈哈。

下面带你轻松搞定美团多渠道打包

  • 下载安装python环境 Python下载地址

  • 下载python脚本 AndroidMultiChannelBuildTool

  • 将ChannelUtil.java代码集成到工程里面,在app启动时获取渠道号传送给后台(如友盟:AnalyticsConfig.setChannel(ChannelUtil.getChannel(this));
  • 在PythonTool/Info/channel.txt中编辑渠道列表,以换行隔开,工程中有示例
  • 打包apk,将apk文件复制到PythonTool目录下(与py同级),运行(直接双击.py文件或者在命令行输入 python MultiChannelBuildTool.py )py脚本即可打包完成。(生成的渠道apk包在output_** 目录下)

由于我们配置环境的时候下载安装了python ,只需下载AndroidMultiChannelBuildTool压缩包解压后是这样的:

把签好名的apk放到py同级目录下,点击不到10秒钟就生成output文件夹并且下面生成了多个渠道包:

总结

时间不早了就写到这里,打包的知识又复习了一遍,写个博客各种截图也是相当的累,其实打包React-Native没有几句代码。

  • 生成自己的签名文件 (.jks或。keystore)
  • 配置gradle文件
  • 写代码混文件
  • 有必要的话生成assets文件夹,并且写入index.android.bundle
  • gradle assembleRelease执行打包命令
  • 有需求的话多渠道打包

好了,做任何一件事都不是简单,唯有自己熟悉做起来才快,好好学习好好生活吧。

come on,enjoy it

安卓转战React-Native之签名打包成Apk并极速多渠道打包相关推荐

  1. python能打包成apk吗_python3代码打包成apk

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 建议先在 airtest ide 中运行,保证脚本的正确性的前提下,再去替换改写 ...

  2. Mac打包Android的apk,[Mac][React Native][Android] 打包成apk

    一旦把app写好之后,最后一个步骤就是打包成apk啰 文档中会提到keytool,gradlew assembleRelease. Android打包APK Android 把包成一个APK主要需要几 ...

  3. Facebook 开源安卓版 React Native,开发者可将相同代码用于网页和 iOS 应用开发

    转自:http://mt.sohu.com/20150915/n421177212.shtml Facebook 创建了React Java 库,这样,Facebook 的工程团队就可以用相同的代码给 ...

  4. 怎么使用Eclipse默认的keystore签名打包成Apk

    2019独角兽企业重金招聘Python工程师标准>>> 1. 首先查看Eclipse的默认的签名文件的位置.点击菜单的Window->Preferences,打开Prefere ...

  5. UE4打包成APK的详细教程(普通安卓应用,VR全景应用尚在探索中,之后若解决会更新)

    因为打包apk的学习过程中没有看到有哪篇文档是把全部流程完整描述出来的(就是给完完全全纯小白的博客,对官方文档的理解也不深的情况下)(也可能是我没搜到过吧)在没理解透的情况下走了很多弯路,这个过程确实 ...

  6. html5游戏封装安卓,html5游戏移植到android并打包成apk,加广告《二》

    html5游戏移植到android并打包成apk,加广告<二> 这篇则讲解开发集成,先看看工程目录结构 ? qqbrowser_sdk_v1.2.jar为X5内核sdk,下载注册开发者 B ...

  7. Expo大作战(十八)--expo如何发布成独立应用程序,打包成apk或者ipa,发布到对应应用商店...

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  8. 转:教大家如何用HBuilder将web项目打包成apk

    链接:https://www.jianshu.com/p/d86bf569295d 将我们的web项目打包成一个apk文件并不难,首先准备好软件HBuilder还有你的项目,注意这里只献给那些不是真正 ...

  9. Cordova将vue项目打包成apk(全使用命令行)

    场景 假设vue项目已经搭建好,要将其打包成apk. 实现 编译vue项目 在vue项目目录下打开cmd,输入: npm run build 新建cordova项目 来到要新建cordova项目的目录 ...

最新文章

  1. node.js的开发流程_Node.js子流程:您需要了解的一切
  2. java对象转json字符串日期格式_fastJSON字符串类型数据中的日期转换为Java bean的日期对象...
  3. python 特性和方法同名_Python语言特性的梳理
  4. Makefile —— 如何在文件内使用变量?
  5. 常用七大经典排序算法总结(C语言描述)
  6. Asp.Net Core WebAPI+PostgreSQL部署在Docker中
  7. 商业项目中代码质量是否重要?
  8. hdu 6203 ping ping ping(贪心+树状数组+dfs序)
  9. Android Studio 使用 Gradle 打包 Jar
  10. Commit Message 规范
  11. 最详细 Spring Boot 入门(-)
  12. python 递归函数 - 刘江的python教程_python 函数 - 刘江的python教程
  13. 数论基础——扩展欧几里得【详细】
  14. Java中的frontcolor_front的用法总结大全
  15. e580显卡驱动_联想e580显卡驱动下载-联想e580笔记本显卡驱动v25.20.15012.2005 官方版 - 极光下载站...
  16. 【BZOJ3991】【SDOI2015】寻宝游戏
  17. 【开发】后端框架——SpringBoot
  18. 用exists代替in真的好么?
  19. 广东外语外贸大学英语文学期末考试复习(解析+细节)2023
  20. c# 控制音量大小 CoreAudioApi

热门文章

  1. 查看zookeeper的版本号
  2. 云宏Ceph分布式存储高性能设计
  3. elementUI使用卡槽二次封装table(亲测可用)
  4. 计算机软考证书含金量和性价比分析
  5. 劳务员培训建筑八大员培训劳务员对劳务分包企业管理的建议
  6. Excel 神器 —— OpenPyXl
  7. 使用Inno Setup 6将exe文件打包成压缩包并设置压缩后自动生成桌面图标
  8. 2016年全国高中数学联赛加试T4分析
  9. 阿里云服务器,解析二级域名
  10. python 标准正态分布函数_Python中的正态分布统计