安卓打造安装包(应用打包、规范处理安装包、安全加固)

安卓打造安装包(应用打包、规范处理安装包、安全加固)文章介绍了应用打包的操作方法以及规范 并推荐一些 APK 加固方案

大家好,欢迎来到IT知识分享网。

本章介绍应用安装包的基本制作规范,主要包括:如何导出既美观又精简的APK文件、如何按照上线规范调整App的相关设置、如何对APK文件进行安全加固以防止安装包被激活成功教程。

应用打包

本节介绍APK安装包的打包过程,包括:如何利用Android Studio导出APK格式的安装包、如何利用Android Studio制作App的个性化图标、如何通过个中国瘦身手段压缩APK文件的大小。

导出APK安装包

  1. 依次选择菜单Build->Generate Signed Bundle/APK…,弹出对话框如下图所示。
    在这里插入图片描述
  2. 选中该窗口左下方的APK选项,再单击Next按钮,进入APK签名对话框,如下图所示。
    在这里插入图片描述
  3. 在该窗口选择待打包的模块名(如chapter10),以及密钥文件的路径,如果原来有密钥文件,就单击Choose existing…按钮,在弹出的文件对话框选择密钥文件。如果首次打包没有密钥文件,就单击Create new…按钮,弹出密钥创建对话框,如下图所示。
    在这里插入图片描述
  4. 单击该Key store path:对话框最右侧的文件夹按钮,弹出如下图的文件对话框,在此可选择密钥文件的保存路径。
    在这里插入图片描述
  5. 在文件对话框中选择文件保存路径,并在下方的File name输入框中填写密钥文件的名字,然后单击OK按钮回到密钥创建对话框。在该对话框依次填写密码(Password)、确认密码(Confirm)、别名(Alias)、别名密码(Password)、别名的确认密码(Confirm),修改密钥文件的有效期限(Validity)。对话框下半部分的输入框只有姓名(First and Last Name)是必填的,填完后的对话框如下图。
    在这里插入图片描述
  6. 单击OK按钮回到APK签名对话框,此时Android Studio自动把密码和别名都填上了,如下图所示。如果一开始选择已存在的密钥文件,这里就要手工输入密码和别名。
    在这里插入图片描述
  7. 单击Next按钮进入下一个打包对话框,如下图所示。对话框上方可选择APK文件的保存路径,对话框中部可选择编译变量(Build Variants),如果是调试用,则编译变量选择release。最后单击Create按钮,等待Android Studio生成AKP安装包。
    在这里插入图片描述
  1. App只能升级不能降级,假如安装包的版本号小于已安装App的版本号,就无法正常安装。版本号在build.gradle.kts中的versionCode节点配置。
  2. 倘若新、旧App的签名不一致,也会造成安装失败。比如该手机之前安装了debug类型的App,现在又要安装release类型的版本,就会出现签名冲突。

制作App图标

新建一个App工程,默认的应用图标都是机器人,如果要发布正规的App,肯定得更换更醒目得专享图标。可是res目录下又好几种分辨率得mipmap-*目录,每种分辨率又有圆角矩形和圆形两类图标,加起来要做十几个图标,倘若每个图标都手工制作,是在要累得够呛。辛好Android Studio早早提供了专门得图标制作插件,只要简简单单几个步骤,即可自动生成所有规格的应用图标。该插件的具体使用步骤如下。

  1. 右击项目结构的模块名称,在右键菜单中依次选择菜单New->ImageAsset,弹出如下图所示的图标制作对话框。
    在这里插入图片描述
  2. 上图所示的对话框左侧是图标的配置选项,右侧是各规格图标的展示效果。在对话框左侧中间找到Path区域,单击路径输入框右边的文件夹图标,在弹出的文件窗口中选择新图标的素材图片,再回到图标制作窗口,此时该对话框的界面如下图所示。
    在这里插入图片描述
  3. 由上图可见,对话框右侧展示区域一下子全部换成了新的图标,完全自动加工好了。接着单击窗口下方的Next按钮,跳转到如下图所示的下一页对话框。
    在这里插入图片描述
  4. 单击下一页窗口中的Finished按钮,借宿图标制作操作,然后再mipmap-*目录下就能看到各种规格的新图标了。

给APK瘦身

App不但要求功能完善,其他方面也得综合考虑,比如APK安装包的文件大小就是很重要的参考因素。具备同样功能的两个安装包,一个很大很占空间,另一个较小不怎么占空间,用户的选择结果自然不言而喻。如何压缩打包后的APK文件大小,也就是所谓的给APK瘦身,这涉及很多技术手段,最常用的主要有3种:去冗余功能、精简无用资源、压缩图片大小。分别介绍如下:

1.去除冗余功能

每当开发者创建新的Android项目,打开模块的AndroidManifest.xml,看到默认的application节点是下面这样的:

<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Chapter10"> 
<application android:allowBackup="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="false" android:theme="@style/Theme.Chapter10"> 

2.精简无用资源

同样打开新项目种模块级别的build.gradle.kts,发现buildTypes节点下面是这样的:

buildTypes { 
    release { 
    isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } 

可见有个isMinifyEnabled 属性,默认值false,该属性的字面意思为是否启用最小化,如果将它设置为true,则Android Studio在打包APK时会惊醒以下代码处理:

  1. 压缩代码,移除各种无用的实体,包括类、接口、方法、属性、临时变量等。
  2. 混淆代码,把类名、属性名、方法名、实例名、变量名替换为简短且无意义的名称,例如Student类的名称可能改为a,方法getName的名称可能改为b等。

App的Java代码经过压缩和混淆之后,打包生成的APK文件会随着变小。除了代码之外,应用项目还包括各种资源文件,若想移除无用的资源文件(包括XML布局和图片),就要引入新属性shrinkResources,并将该属性值设置为true,这样Android Studio在打包APK时会自动移除无用的资源文件。同时开启代码压缩和资源压缩的buildTypes节点示例如下:

buildTypes { 
    release { 
    isMinifyEnabled = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } 

3.压缩图片大小

规范处理

本节介绍App上线前必做的准备工作,包括:如何正确设置App的版本编号和版本名称、如何把App从调试模式切换到发布模式、如何给多个渠道同时打包APK文件。

版本设置

  • 版本号比已安装的版本号小,在安装时系统直接提示失败,因为App只能做升级操作,不能做降级操作。
  • 在升级系统应用(手机厂商内置的应用,非普通应用)时,如果只修改versionName,没修改versionCode,重启手机后会发现更新丢失,该应用被还原到升级前的版本。这是因为:对于系统应用,Android会检查versionCode的数值,如果versionCode不大于当前已安装的版本号,本次更新就被忽略了。

除了系统要求检查应用的基础信息,App又是也需要获取自身信息,比如应用图标可以从资源图片获取,应用名称可调用getString方法来获取。其他像应用包名、应用版本等信息,可以编译配置工具defaultConfig获取,该类提供了几个配置属性说明如下:

  • applicationId:应用包名。
  • buildTypes:编译类型。为debug表示这是调试包,为release表示这是发布包。
  • versionCode:应用的版本编号。
  • versionName:应用的版本名称。

下面是获取App基础信息的代码例子:

public class AppVersionActivity extends AppCompatActivity { 
    private static final String TAG = "AppVersionActivity"; @Override protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); setContentView(R.layout.activity_app_version); ImageView iv_icon = findViewById(R.id.iv_icon); iv_icon.setImageResource(R.mipmap.ic_launcher); // 应用图标取自ic_launcher TextView tv_desc = findViewById(R.id.tv_desc); try { 
    PackageManager packageManager = getPackageManager(); PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0); // 应用名称取自app_name,应用包名、版本号、版本名称均来自BuildConfig String desc = String.format("App名称为:%s\nApp包名为:%s\n" + "App版本号为:%d\nApp版本名称为:%s", getString(R.string.app_name), packageInfo.packageName, packageInfo.getLongVersionCode(), packageInfo.versionName); tv_desc.setText(desc); } catch (PackageManager.NameNotFoundException e) { 
    e.printStackTrace(); Log.d(TAG, "exception:" + e.getMessage()); } } } 

发布模式

  1. 保护用户的铭感账户信息不被泄露。
  2. 保护业务逻辑与流程处理的交互数据不被泄露。

1.Log日志

Log工具用于打印调试日志。在App运行过程中,日志信息会输出到Logcat窗口。因为最终用户不关心App日志,所以除非特殊情况,发布上线的App应屏蔽所有日志信息。下面是封装了调试模式的Log工具代码:

public class LogUtil { 
    public static boolean isDebug = false; // 标志位需要在启动App时同步 public static void v(String tag, String msg) { 
    if (isDebug) { 
    Log.v(tag, msg); // 打印冗余日志 } } public static void d(String tag, String msg) { 
    if (isDebug) { 
    Log.d(tag, msg); // 打印调试日志 } } public static void i(String tag, String msg) { 
    if (isDebug) { 
    Log.i(tag, msg); // 打印一般日志 } } public static void w(String tag, String msg) { 
    if (isDebug) { 
    Log.w(tag, msg); // 打印警告日志 } } public static void e(String tag, String msg) { 
    if (isDebug) { 
    Log.e(tag, msg); // 打印错误日志 } } } 

2.提示Toast

Toast工具在界面下方弹出小窗,给用户一两句话的提示,小窗暂停一会后消失。由于Toast窗口无交互动作,样式也基本固定,因此除了少数弹窗在发布时予以保留,其他弹窗都应在发布时屏蔽。下面是封装了调试模式的Toast工具代码:

public class ToastUtil { 
    public static boolean isDebug = false; // 标志位需要在启动App时同步 // 不管发布模式还是调试模式,都弹出提示文字 public static void show(Context ctx, String desc) { 
    Toast.makeText(ctx, desc, Toast.LENGTH_SHORT).show(); } // 调试模式下弹出短暂提示 public static void showShort(Context ctx, String desc) { 
    if (isDebug) { 
    Toast.makeText(ctx, desc, Toast.LENGTH_SHORT).show(); } } // 调试模式下弹出长久提示 public static void showLong(Context ctx, String desc) { 
    if (isDebug) { 
    Toast.makeText(ctx, desc, Toast.LENGTH_LONG).show(); } } } 

除此之外,AndroidManifest.xml也要区分发布模式与调试模式。应用上架之后,若无特殊情况,开发者都不希望activity和service对外部开放,所以要在activity和service标签下分别添加属性android:exported="false",表示该组件不允许对外开放。

多渠道打包

对于很对大型App来说,针对不同渠道进行精细化运营是必不可少的,并且客观上也要求对App分渠道管理。这里所谓的渠道,指的是提供App下载的各大应用商店,尤其是各大手机厂商预装的自家应用商店,包括荣耀、小米、OPPO、vivo等品牌。根据不同渠道打造对应的App安装包,带来的好处包括但不限于以下几点:

  1. 各厂商的底层系统有着不同的适配要求,需要分别加以定制。
  2. 有助于统计各家渠道的App下载量、用户数量以及业务交易量。
  3. 有助于统计各家厂商的App用户分别展开精准营销活动。
android { 
    // ...... flavorDimensions += "version" productFlavors { 
    create("honor") { 
    dimension = "version" applicationIdSuffix = ".honor" versionNameSuffix = "-honor" } create("xiaomi") { 
    dimension = "version" applicationIdSuffix = ".xiaomi" versionNameSuffix = "-xiaomi" } create("oppo") { 
    dimension = "version" applicationIdSuffix = ".oppo" versionNameSuffix = "-oppo" } create("vivo") { 
    dimension = "version" applicationIdSuffix = ".vivo" versionNameSuffix = "-vivo" } } } 

安全加固

本节介绍如何对APK安装包进行安全加固:首先通过反编译工具成功激活成功教程App源码,从而表明对APK实施安全防护的必要性;然后说明代码混淆的开关配置,并演示代码混淆如何加大源码激活成功教程的难度;最后描述怎样利用第三方加固网站对APK进行加固,以及如何对加固包进行重签名。

反编译

  • apktool:对APK文件解包,主要用来解析res资源和AndroidManifest.xml。
  • dex2jar:将APK包中的classes.dex转为JAR包,JAR包就是Java代码的编译文件。
  • jd-gui:将JAR包反编译为Java源码。

以Windows环境为例,下面是反编译APK的具体步骤。

  1. 依次选择开始菜单->Windows系统->命令提示符,打开命令窗口,进入apktool所在目录,运行命令“apktool.bat d -f 解包后的保存目录 待处理的APK文件名”,等待反编译过程,如下图所示。
    在这里插入图片描述
    反编译完成,即可在apktool目录下看到激活成功教程目录。apktool的用途是解析出res资源,包括AndroidManifest.xml和res/layout、res/values、res/drawable等目录下的资源文件。

  2. 用压缩软件(如WinRAR)打开APK文件,发现APK安装包其实是一个压缩文件,使用WinRAR打开的APK文件的目录结构如下图。
    在这里插入图片描述
    先从APK包中解出classes.dex文件,并打开classes.dex将dex开头改为036(据了解dex2jar-2.0版本的工具只支持dex开头字节为035和036的Android版本,由于高版本的Android编译生成的dex开头字节不同,如Android 7.0的dex开头字节是037,Android 8.0的dex开头字节是038,Android9.0的dex的开头字节是039)。
    再进入dex2jar所在的目录,运行命令.\d2j-dex2jar.bat classes.dex,等待转换过程,如下图。
    在这里插入图片描述
    转换完毕即可在dex2jar目录下看到新文件classes-dex2jar.jar,该JAR包即为Java源码的编译文件。




  3. 双击打开jd-gui.exe,用鼠标把第二步生成的classes-dex2jar.jar拖到jd-gui界面中,程序就会自动将JAR包反编译为Java源码,反编译后的Java源码目录结构如下:
    在这里插入图片描述

代码混淆

前面讲到反编译就能够激活成功教程App的工程源码,因此有必要对App源码采取防护措施,代码混淆就是保护代码安全的措施之一。Android Studio已经自带混淆器ProGuard,它的用途主要有下列两点:

  1. 压缩APK包的大小,删除无用代码,并简化部分类名和方法名。
  2. 加大激活成功教程源码的难度,部分类名和方法名被重命名使得程序逻辑变得难以理解。

代码混淆的配置文件其实一直存在,每次在Android Studio新建一个模块,该模块的根目录下会自动生成文件proguard-rules.pro。打开build.gradle.kts,在android->buildTypes->release节点下可以看到两行编译配置,其中便用到了proguard-rules.pro:

isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) 

第三方加固及重签名

工程源码

文章涉及的所有代码可点击工程源码下载。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/127697.html

(0)
上一篇 2025-09-05 19:26
下一篇 2025-09-05 19:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信