导航:首页 > 操作系统 > android热更新原理

android热更新原理

发布时间:2023-02-14 12:30:30

‘壹’ 用通俗的语言解释冷更新和热更新。

热更新是指软件不通过运营商店的软件版本更新审核,直接通过应用自行下载的软件数据更新的行为。简单来说,就是在用户下载安装APP之后,打开App时遇到的即时更新。热更新是一种各大手游等众多App常用的更新方式。

冷更新差不多就是重装的意思,用户主动从网络、存储介质(光驱、u盘等)来获取安装包,进行安装的过程。而热更新,是程序自主从安装渠道(一般是网络)进行更新升级的过程。

工作原理

热更新就是动态下发代码,它可以使开发者在不发布新版本的情况下,修复 BUG 和发布功能,让开发者得以绕开苹果的审核机制,避免长时间的审核等待以及多次被拒造成的成本。

技术特点

在iOS中有两种App更新方式:一种是在AppStore内进行更新,更新时重新下载全部安装包;另一种就是热更新,用户只有在打开App时才会发现热更新包,更新时只需下载安装更新部分的代码,再次打开时即可。热更新最大的优点就是快,它可以绕过苹果方面的审核,更新通常只需一个晚上即可上线,另一大优点就是更新包较小,一般都在1M左右,用户不连接WiFi也可随意下载。

‘贰’ 安卓动态加载jar实现类似热更新功能

shift + 鼠标右键打开命令行,输入dx --dex --output=qula_dex.jar qula.jar

执行成功后

public class FileUtils {

public static void Files(Context context, String fileName, File desFile) {

InputStream in =null;

OutputStream out =null;

try {

in = context.getApplicationContext().getAssets().open(fileName);

out =new FileOutputStream(desFile.getAbsolutePath());

byte[] bytes =new byte[1024];

int i;

while ((i = in.read(bytes)) != -1){

out.write(bytes,0, i);

}

}catch (IOException e) {

e.printStackTrace();

}finally {

try {

if (in !=null)

in.close();

if (out !=null)

out.close();

}catch (IOException e) {

e.printStackTrace();

}

}

}

public static boolean hasExternalStorage() {

return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);

}

/**

    * 获取缓存路径

    * @param context

    * @return 返回缓存文件路径

    */

    public static File getCacheDir(Context context) {

File cache;

if (hasExternalStorage()) {

cache = context.getExternalCacheDir();

}else {

cache = context.getCacheDir();

}

if (!cache.exists()){

cache.mkdirs();

}

return cache;

}

}

/**

* 加载dex文件中的class,并调用其中的sayHello方法

*/

private void loadDexClass() {

File cacheFile = FileUtils.getCacheDir(context);

String internalPath = cacheFile.getAbsolutePath() + File.separator +"qula_dex.jar";

File desFile =new File(internalPath);

try {

if (!desFile.exists()) {

desFile.createNewFile();

FileUtils.Files(context,"qula_dex.jar", desFile);

}

}catch (IOException e) {

e.printStackTrace();

}

//下面开始加载dex class

    DexClassLoader dexClassLoader =new DexClassLoader(internalPath,

cacheFile.getAbsolutePath(),null,context.getClassLoader());

try {

//加载的类名为jar文件里面完整类名,写错会找不到此类hh

        Class libClazz = dexClassLoader.loadClass("com.justcodeit.xiaoshuo.netbook.BookFactory_qula");

loadBook = (IBookLoadFactory) libClazz.newInstance();

if (loadBook !=null)

Toast.makeText(context,"版本号" +loadBook.getVersion(), Toast.LENGTH_LONG).show();

}catch (Exception e) {

e.printStackTrace();

}

}

‘叁’ 安卓12带来新功能,终于不用等进度条了

想用手机玩 游戏 一共分几步?第一步下载 游戏 ,第二步等待 游戏 大几个GB的热更新,第三步,所有更新完成后才能拿起手机快乐玩耍。虽然玩 游戏 很快乐,但是漫长的更新的过程,特别是大量的热更新,很磨人,好在这种问题或许在未来有机会缓解。

昨日,谷歌举行 游戏 开发者峰会,推出了全新的开发工具和解决方案,让基于安卓和Chrome 操作系统的 游戏 开发变得更为简单。值得注意的是,本次峰会还讲到了android 12在 游戏 方面的改进,比如用户可以边下边玩。

1.玩 游戏 不再等待

“边下边玩”功能目前仅适用于Android 12设备,这项功能可以有效缩短下载大型 游戏 时的等待时间。当用户在Google Play下载 游戏 之后,仅需等待几秒钟就能进入 游戏 界面,开始玩 游戏 ,而 游戏 包仍在后台继续下载。

这项功能在原理上与迅雷的“边下边播”有些类似,经过数秒的等待后,用户便可以直接进入 游戏 ,不需要等整个 游戏 下完,400MB 大小的 游戏 只需 10 秒即可开始游玩。这项功能对于Xbox、PS平台的主机玩家而言并不陌生,因为这两种 游戏 主机已经提供了类似的功能,但是这项功能在安卓手机上实现还是第一次。

不过对于手机端的“边下边玩”,实际游玩体验如何,画质表现如何等问题,谷歌并没有提及,预计在之后的测试中,会有更为明确的测试结论。另外,国内手机厂商会针对安卓系统进行个性化、品牌化、本地化处理,会针对功能做出一些修改和完善,或许届时这项功能会以一种更为完备,或者以另一种形式出现也并非不可能。

2. 游戏 仪表盘,自定义 游戏 参数

Android 12新增 游戏 仪表盘功能,这项功能可以让用户自定义 游戏 运行的各项参数,还提供了 游戏 直播快捷键、 游戏 数据小部件、屏幕录制、截屏、帧数监测和免打扰按钮等功能。

另外, 游戏 仪表盘这次还增加了性能模式调节功能,这项功能与手机-电源选项中的性能模式有所不同,它是可以针对 游戏 而独立设置的。目前,性能模式有性能、标准和省电三种模式,选择之后,系统会自动为该 游戏 记忆性能配置,下次打开 游戏 不需要重新设置。

这项功能的意义在于玩家可以针对 游戏 单独调整性能输出,例如《原神》、《和平精英》、《崩坏3》这样的 游戏 ,大可用性能模式火力全开,而对于消消乐等休闲 游戏 ,便可以选择“标准”或“省电”模式,适当降低性能输出,动态降低功耗。

3.Android 12代码曝光新机和自研芯片

开发者在Andorid 12新 游戏 模式的API文档中,发现了谷歌下一代Pixel系列的命名——Pixel 6和Pixel 6 XL,将搭载谷歌自研的处理器平台。目前,该系列手机的真机图也在网上曝光。

Pixel 6系列的外观相比上一代不能说不一样,只能说是完全不同,整部手机的设计语言都有了非常大的改变,特别是手机背面的辨识度直接拉满。

该系列手机正面搭载一块6.71英寸居中打孔屏,开孔非常小,而Pixel 6 XL搭载的是一块曲面屏,四周边框控制得非常好,大大提升了正面屏幕的屏占比以及整体的观感。

不过相比正面,背面设计更为大胆。手机背面被分为三段,相机模组部分凸起,摄像头横向排布。但不同的是,Pixel 6搭载了5000万像素主摄+1200万像素超广角摄像头,XL版本在前者的基础上增加了一颗4800万像素长焦摄像头,而且这颗长焦摄像头很有可能还是一颗潜望式摄像头,所以XL版本的凸起部分也更宽。在配色选择上,Pixel 6 XL将会有4种颜色选择,而Pixel 6只有一种。

除了大胆的外观设计,自研芯片也是Pixel 6系列的重点之一。该系列将全系搭载谷歌自研的处理器平台,采用5nm芯片制程,由谷歌和三星半导体部门联合开发。在性能表现上,这款处理器与高通骁龙870大致相当。另外,Pixel 6将配备8GB+128/256GB两种内存组合,内置4614mAh电池,XL则配备12GB RAM,有128/256/512GB三种存储规格,电池容量增加到5000mAh。

结合之前已经公布的内容,Android 12是一个干货满满的新系统,这款系统将在今年秋季开启推送,预计届时Pixel 6系列手机也会与消费者见面。

‘肆’ 安卓热更新违规吗

违规
其实无论是安卓还是iOS,规则上都是不允许“热更新”的。只不过以前iOS并没有特别严格的限制,安卓是由于开源且其服务在国内不能使用,所以形同虚设。禁止热更新有利有弊。有利的是,禁止热更新,更能够保证用户的安全性。不利的是,每次都需要下载一个完整的应用,耗费流量。
如果平台支持热更新的话,客户端在更新的时候不需要重打包,玩家不需要重新进入网站下载最新安装包,而直接在大厅内部检测更新文件唯一标识码,自动下载更新替换文件。

‘伍’ android热更新框架哪个好

一.基础知识

1.阿里的热更新框架已经开源 了。但已经很久没有更新过新版本了。当前的版本只支持到了 Android 4.4。由于 5.0 起新的 ART 虚拟机、更严格的 SELinux 策略以及对 64 位的支持之类的事,使得 Xposed 都在开发上做了很多调整。我不知道 Dexposed 现在是否支持,但至少阿里没有开源。

2.在本地动态执行远端下发的代码是极度危险的行为。利用此方法执行非法代码等或用于绕过 Google Play 等市场的审查是违反相关协议的,也是对用户极度不负责任的行为。

3.在一些访问非常密集的地方使用热更新可能会对效率产生相对比较大的影响,应该避免使用.

4.我们可以对 Java 的 ScriptEngine 进行一些封装成为一个 HotPatch 类使得它更适合做热更新的工作。

5.首先,检查热更新补丁的管道一定要建立在 https 上,因为下发代码是极其危险的,如果被劫持,后果是无法想象的。其次,请求时最好自动带上 Android 版本、手机型号、地区、版本号等信息,以方便更精确地下发,千万不能下发错。

6.Java在运行时加载对应的类是通过ClassLoader来实现的,ClassLoader本身是一个抽象来,Android中使用PathClassLoader类作为Android的默认的类加载器

7.我们的如果想做hotpatch,一定要保证我们的hotpacth dex文件出现在dexElements列表的前面。

二.常用的热更新技术框架:

基于QQ空间的HotFix →→ 要使用到android dex分包方案→拆分dex的项目的话,可以参考一下谷歌的multidex方案实现.

大众点评的NuWa←项目补丁自动化做的很完整
alibaba/AndFix

阿里巴巴的DexPosed
dalvik_patch实现multidex
使用React-Native实现app热部署的一次实践
alibaba/AndFix

三、常用的热更新技术框架比较

Advantage
disadavantage
NuWa
1,可以新增类和字段,
2,兼容到6.0系统
1,基本原理是classloader,类加载器
2,不能修改资源文件,如图片布局等(可通过动态布局实现)
AndFix
1, 支持Android2.3到6.0版本
2, 支持arm与x86系统架构
3, 支持dalvik和ART的runtime
4, 不需要重启App即可应用补丁
1,不能新增类和字段,
2,不能修改资源文件,
3,不能修改manifest文件
4,不能新增成员变量
5,不能使用加固后的apk制作pacth文件
四、github地址
网络的同学的实现 HotFix
点评的同学的实现 Nuwa
阿里的同学的实现 AndFix
另:AndFix对static的支持不太好,下面是试验的Demo:
添加了一个静态的字段addString:

通过AndFix来制作patch会直接报错:

‘陆’ Android开发Tinker热更新的问题

通过阅读官方的技术文档,始终没有发现有对这个情况的相关配置项,所以只能从别处下手,最后发现,通过在 app mole 的 “build.gradle” 文件中,注释掉依赖插件脚本,最终解决掉这个问题:

说两句:
目前运行调试一切正常,不过要始终留意后续是否会出现问题;重要的一点是,当要打包新版本时,一定要解开这个注释。

2、can’t the get signConfig for this build

问题:
执行 buildTinkerPatchRelease 打 Release 版本补丁包时报以下错误:

Error:Execution failed for task ':app:tinkerPatchRelease'.
> can't the get signConfig for this build
1
2

解决:

android {
...
// 签名配置【buildTypes中调用了signingConfigs,则signingConfigs{}要置于buildTypes{}前面】
signingConfigs {
release {
try {
storeFile file("MyProject.jks")
storePassword "111111"
keyAlias "zhangzeqiao"
keyPassword "111111"
} catch (ex) {
throw new InvalidUserDataException(ex.toString())
}
}
}

buildTypes {
release {
...
signingConfig signingConfigs.release
}
debug {
...
signingConfig signingConfigs.release
}
}
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
其中要特别注意,signingConfigs{} 方法体要置于 buildTypes{} 方法体前面,不然会报以下错误:

‘柒’ Android 插件化

原理:实现原理上都选择尽量少的hook,通过在manifest上预埋一些组件实现四大组件的插件化。其中Small更形成了一个跨平台、组件化的框架。

VirtulApp:
能够完全模拟app的运行环境,能够实现免安装应用和双开技术。
Atlas:
阿里出品,号称是一个容器化框架,结合了组件化和热更新技术。

Android中有两种类加载器,DexClassLoader和PathClassLoader,它们都继承于BaseDexClassLoader。

两者的区别:DexClassLoader多了一个optimizedDirectory的路径参数,这个目录必须是内部存储路径,用于缓存系统创建的Dex文件。

所以我们可以使用DexClassLoader去加载外部Apk中的类。

ClassLoader调用loadClass方法加载类采用了双亲委托机制来避免重复加载类。
首先,ClassLoader会查看自身已经加载的类中是否已经存在此类,如不存在,然后,则会使用父类来加载此类,如不能成功加载,则会使用自身重载于BaseDexClassLoader的findClass()方法来加载此类。

DexClass的DexPathList在DexClass的构造器中生成,findClass()方法则是从DexPathList下面找出对应的DexFile,循环DexElements,通过dexElement.dexFile取出对应的DexFile,再通过DexFile.loadClassBinaryName()加载对应的类。

作用:使用插件DexClassLoader加载出需要的类。

通过每一个插件的DexClassLoader加载出自身所需要的类,当每一个插件需要加载相同的类库时,可采用该类库的不同版本来使用。

通过把每一个插件的pathList(DexFile)合并到主app的DexClassLoader上,来使各个插件和主app直接能够相互调用类和方法,并且各个插件中相同的功能可以抽取出来作为一个Common插件供其它插件使用。

插件调用主工程
在ClassLoader构造时指定主工程的DexClassLoader为父加载器即可直接调用主工程中的类和方法。
主工程调用插件
如果是多DexClassLoader的情况,则需要通过插件的DexClassLoader加载对应的类并反射调用其方法。此种情况,主工程一般会在一个统一的地方对访问插件中的类和方法做一些访问权限的管理及配置。

如果是单DexClassLoader的情况,则可以直接调用插件中的类和方法。但是当多个插件引用的库的版本不同时,会出现错误,因此,建议采用Gradle版本依赖管理统一处理主工程及各个插件的库依赖。

Android通过Resource来加载资源,只要有插件apk,就可以使用assertManager.addAssertPath(apkPath)的方式来生成assertManager,再使用其new出对应的Resource对象即可。

注意:由于AssertManager并不是Public,所以需要通过反射的方式去调用它。并且由于一些Rom对Resource的处理,所以,需要兼容处理。

有2种处理方式:

产生的原因:由于主工程和各个插件引用的Resource id重复产生的冲突。

解决思路:Android中的资源在系统中是以8位16进制0XPPTTRRRR的方式存在,其中PP即是资源区分的区域(Android系统只用它来区分系统资源和应用资源),只要让每一个插件的PP段取不同的值即可解决资源id冲突的问题。
具体解决方式:

1.修改aapt源码编译期修改PP段。
2.修改Resource的arsc文件,其中的每一条都包含了资源id和映射路径。

Activity的处理最为复杂,有两种处理方式:
1.ProxyActivity的方式。
2.预埋StubActivity,hook系统启动Activity的过程。

原理:VirtualAPK通过替换了系统的Instrumentation,hook了Activity的启动和创建,省去了手动管理插件Activity生命周期的繁琐,让插件Activity像正常的Activity一样被系统管理,并且插件Activity在开发时和常规一样,即能独立运行又能作为插件被主工程调用。

Android插件化方向主要有2个方向:

Android 插件化

‘捌’ android热更新是什么意思

我们知道Java在运行时加载对应的类是通过ClassLoader来实现的,ClassLoader本身是一个抽象来,Android中使用PathClassLoader类作为Android的默认的类加载器,
PathClassLoader其实实现的就是简单的从文件系统中加载类文件。PathClassLoade本身继承自BaseDexClassLoader,BaseDexClassLoader重写了findClass方法,
该方法是ClassLoader的核心

‘玖’ react native能解决热更新问题吗

上一篇和大家分享了如何在Android 现有App中集成React Native。本篇博客同样是react Native中比较经典的内容:热更新部署。
android原生App中我们实现热修复有很多种选择:Tinker、hotFix、Qzone的热更新等等。基本的思路都是大同小异的。React Native中的热更新有点像App的版本更新,也就是根据查询server端的版本和手机端目前App的版本进行对比,然后来执行是否更新的操作。根本原因在于react native的加载启动机制:React Native会将一系列资源打包成js bundle文件,系统加载js bundle文件,解析并渲染。所以,React Native热更新的根本原理就是更换js bundle文件,并重新加载,新的内容就完美的展示出来了。微软为我们提供了CodePush来简化热更新的操作,但是由于速度等原因在国内并没有备受青睐。本篇内容就以自己服务器来更新的方式实现。

‘拾’ Android版微信的增量升级包是什么原理

升级机制:
我们打算采用delta编码的patch升级Android应用。新的升级机制可以描述如下:

1、 在服务器上生成一个patch。
2、 下载patch到手机中。
3、 通过补丁获取一个已安装应用的新的安装apk。
4、 安装应用的新版本并删掉旧的版本和patch。

统计数据:
我们当前正在研究应用怎样在android中升级。这个研究结果将允许我们在新的升级机制下节约大量的流量。我们创建了一个android应用用来收集统计数据(可能会用于将来的研究)。
应用会收集以下数据:
1、 应用的名字,版本,大小和每个应用最后升级的时间。
2、 统计Wifi和3G的链接状态。

谷歌增量升级技术:

在谷歌2012 I/O大会上宣布Google Play Stroe的增量升级技术。它始于八月中旬。他们使用跟我们相同的升级机制。比较两个应用的不同,并将patch部署在终端上。

阅读全文

与android热更新原理相关的资料

热点内容
华为amd云服务器 浏览:495
汉化编程卡是什么意思 浏览:126
python学习pdf 浏览:313
祝绪丹程序员那么可爱拍吻戏 浏览:198
asp源码会员消费系统 浏览:113
java反射设置 浏览:152
python一行文 浏览:439
排序算法优缺点 浏览:563
恶搞加密文件pdf 浏览:674
gif怎么压缩图片大小 浏览:217
命令选择当前不可用 浏览:158
欧几里得算法如何求逆元 浏览:506
男中学生上课解压神器 浏览:373
加密狗拔掉之后怎么办 浏览:27
云储存平台源码 浏览:847
解压文件苹果手机rar 浏览:149
centos开机命令行模式 浏览:697
遍历所有listpython 浏览:660
力控加密文件夹 浏览:517
如何更改移动服务器密码 浏览:686