概述
我们发布了一个新的应用后,由于发布的应用并不完美,可能会出现一些bug,而且为了与时俱进,添加一些新的功能,就需要开发人员对其进行维护与升级。那么,发布后的apk被下载到用户的手机上之后,开发人员该如何对其进行后续的操作呢?
为了对旧应用进行维护与升级,首先我们要在用户的手机中找到旧应用。那么,我们该如何在Android系统中精确定位到我们的应用呢?
Android的应用程序在Android系统中具有唯一标识,即包名(package),可以在AndroidManifest文件中进行设置。但要注意,应用程序的源文件一定要在包名所指向的路径中。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.XXX.XXX.XXX">
Java的包的命名规范中,包一般采用反写域名命名规则,即com.xx.xxx.xxxx形式,且全部使用小写字母。
一级包名为com,二级包名为xx(一般为公司或个人域名),三级包名根据应用进行命名,四级包名为功能模块名。如:com.tencent.qq.activitys,这样具备较高可读性,一看就知道是腾讯公司QQ软件中存放activity的包。
下面是一些常见的包的组织方式的命名。
com.example.app.activitys | 用来组织Activity类 |
com.example.app.base | 基础共享的类,如多个Activity共享的 BaseActivity或整个应用共享的MyApplication类 |
com.example.app.adapter | 项目中用到的适配器类 |
com.example.app.view | 自定义的View,如常用的TitleBarView |
com.example.app.util | 工具类,如HttpUtil,ImageUtil,FileUtil |
com.example.app.db | 数据库类,如DataBaseHelper,MessageDB |
com.example.app.service | 服务类,如GetMsgService |
com.example.app.constant | 常量类 |
com.example.app.domain/modle/entity | 元素实体类,如对应注册用户信息的User类, 对应聊天信息的TextMessage类 |
com.example.app.broadcast | 广播服务类 |
在自己开发应用时,一定要保证包的名字的不同,这样Android系统便不会混淆。否则,先安装的app将被后安装的app所覆盖。
但是,Android系统的开发者无穷无数,每个开发者都无法保证自己开发的应用的包名不会和其它开发者开发的应用重复。于是,Android系统在包名识别之外,还添加了签名
识别。
签名之前首先要创建一个密钥库,设置密钥库的位置和密码,之后填写密钥库的信息,并在密钥库中设置密钥。最后,使用密钥就可以生成带签名的apk文件了。
在IntelliJ IDEA中,依次点击Build->Generate Signed APK,按照提示进行操作即可。
添加了签名之后的应用被安装之后,再次安装相同包名的应用之时,Android系统便会提出询问,是否删除之前安装的应用,而不会简单的覆盖。只有当包名和签名均相同时,Android系统才会将旧的应用用新的应用覆盖掉。
使用了签名和包名,我们的应用程序在Android系统中便可以变得独一无二了。
了解了签名和包名之后,想要对我们的应用程序进行升级就简单多了。我们只要重新发布一款包名和签名均与旧的应用一致的新应用,通知用户下载,便可以将旧应用覆盖掉,实现应用的升级。
app升级操作分为两种:
- App Store升级
在App Store中升级需要为App Store上传新版App,我们在新版本完成之后都会上传到App Store中,不同的应用市场审核的时间不同,一般除了第一次上传时间较长之外,其余的审核都是挺快的,一般不会超过半天(不排除例外情况),在审核完成之后就相当于完成了这个应用市场的发布了,也就是发布上线了。这时候如果用户安装了这个应用市场,那么就能看到我们的App有新版本的升级提醒了。
- 应用内升级
除了可以在应用市场升级,我们还可以在应用内升级,在应用内升级主要是通过调用服务器端接口获取应用的升级信息,然后通过获取的服务器升级应用信息与本地的App版本比对,若服务器下发的最新的App版本高于本地的版本号,则说明有新版本发布,那么我们就可以执行更新操作了,否则忽略掉即可。
Android应用程序的版本标识分为版本名(versionname)与版本号(versioncode),在AndroidManifest文件中进行设置。注意,当使用gradle框架时,在build.gradle文件中,同样可以设置app的版本名与版本号,当两个文件的设置发生冲突时,将默认使用build.gradle文件中的设置。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="2"
android:versionName="1.1"
package="com.XX.XXX.XXXX">
在应用程序中,可以通过PackageManager来获得包的版本信息。
/**
* 获取版本号
* @return 当前应用的版本号
*/
public String getVersion() {
try {
PackageManager manager = this.getPackageManager();
PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0);;
return info.versionName + info.versionCode;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
之后将版本名和版本号与服务器最新版本的版本名和版本号进行比较,确认是否需要更新即可。
我们开发的应用程序难免会出现bug,但在每次出现bug时,都选择重新打包上线,自然不是一个好选择,这会严重影响用户的体验。有没有一种可以以补丁的形式发布,无需重新下载安装即可修复bug的方法?答案是肯定的。这就是Android的热修复。下面将分析一下热修复的原理,几大开源框架,以及热修复的使用。
下面的文字参考自 一片枫叶的专栏
热修复的原理主要有以下两种:
1.通过更改dex文件的加载顺序实现热修复,其核心原理就是通过更改含有bug的dex文件的加载顺序。在dex的加载中,若以找到方法则不会继续查找,所以如果能让修复之后的方法在含有bug的方法之前加载就能达到修复bug的目的。此种方法在修复bug完成后,需要重启app。
2.通过Native替换方法指针的方式实现热修复。相比于第一种的在Java层实现,此种方法主要在Native层实现,且不需要对app进行重启。针对此方法,目前主要有阿里开源的两个热修复框架:Dexpost和AndFix
最终我们App的热修复方案选择的是AndFix,原因有三:
(1)AndFix支持Android2.3-6.0,所以在机型上的是适配上是没问题的;
(2)AndFix是由阿里开源的,并且持续维护中,目前不少公司已经使用其作为自身App的热修复方案;
(3)通过修改Dex加载顺序的方式实现热修复需要重新启动App,并且相应的开源框架多多少少存在着问题,没有持续的维护;
因此我们最终选择了AndFix作为我们的开源方案。具体的AndFix集成方式可参考github中AndFix的介绍
这里简单介绍一下具体的继承流程
(1)在App的Application的onCreate方法中执行AndFix的初始化操作;
(2)判断服务器端是否有可更新的热修复差异包
(3)若无则直接退出,若有则下载并执行修复动作
(4)修复完成之后删除下载的补丁差异包
(5)在判断服务器端是否有可更新的补丁包的时候可添加灰度,如版本,渠道,用户等,实现对补丁包定制化的修复
另外需要说明的是:若一个版本中存在着多个bug,则一般的都是让后一个补丁包覆盖前一个补丁包,并删除前一个补丁包,简单来说就是对于每一个版本至多有一个补丁包。
最后
以上就是负责皮皮虾为你收集整理的Android apk的维护与升级的全部内容,希望文章能够帮你解决Android apk的维护与升级所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复