CN115129348A - 应用程序的资源更新方法、装置、设备及可读存储介质 - Google Patents

应用程序的资源更新方法、装置、设备及可读存储介质 Download PDF

Info

Publication number
CN115129348A
CN115129348A CN202210788001.1A CN202210788001A CN115129348A CN 115129348 A CN115129348 A CN 115129348A CN 202210788001 A CN202210788001 A CN 202210788001A CN 115129348 A CN115129348 A CN 115129348A
Authority
CN
China
Prior art keywords
class
loader
class loader
target
resource
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
CN202210788001.1A
Other languages
English (en)
Inventor
刘鸿达
郭润增
王少鸣
张志强
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Tencent Technology Shenzhen Co Ltd
Original Assignee
Tencent Technology Shenzhen Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Tencent Technology Shenzhen Co Ltd filed Critical Tencent Technology Shenzhen Co Ltd
Priority to CN202210788001.1A priority Critical patent/CN115129348A/zh
Publication of CN115129348A publication Critical patent/CN115129348A/zh
Pending legal-status Critical Current

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/60Software deployment
    • G06F8/65Updates
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/44Arrangements for executing specific programs
    • G06F9/445Program loading or initiating
    • G06F9/44521Dynamic linking or loading; Link editing at or after load time, e.g. Java class loading
    • G06F9/44526Plug-ins; Add-ons

Landscapes

  • Engineering & Computer Science (AREA)
  • Software Systems (AREA)
  • Theoretical Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Computer Security & Cryptography (AREA)
  • Stored Programmes (AREA)

Abstract

本申请提供了一种应用程序的资源更新方法、装置;方法包括:在应用程序运行过程中,获取应用程序的更新资源包,更新资源包中包括更新资源及可执行文件;基于可执行文件,创建更新资源包对应的插件类加载器,并生成包括至少一个非插件类加载器的类加载器集合;在应用程序对应的类加载器链中,获取宿主类加载器,并将宿主类加载器的父类加载器替换为插件类加载器,得到目标类加载器链;基于类加载器集合、目标类加载器链中至少之一,确定用于加载更新资源归属的目标类的目标类加载器;通过目标类加载器加载目标类,并基于更新资源,运行目标类对应的功能。通过本申请,能够在程序运行中,实现应用程序的更新,提高应用程序的更新效率。

Description

应用程序的资源更新方法、装置、设备及可读存储介质
技术领域
本申请涉及计算机技术领域,尤其涉及一种应用程序的资源更新方法、装置、设备、计算机可读存储介质及计算机程序产品。
背景技术
随着计算机技术的普及,计算机中的应用程序越来越多。在实际使用过程中,应用程序的各种功能通过更新可以不断的得以完善。
然而,在相关技术中,应用程序不管是更新多少内容,需要重新打包、测试、在对应的渠道换安装包、提示用户升级、用户升级后进行覆盖安装等步骤。针对应用程序的更新过程比较复杂,需要耗费过多的人力以及成本,同时在更新应用程序时,需要重启应用程序,在直播、支付等应用场景中,正在执行的业务流程被迫中断,人机交互体验差、应用程序更新效率低。
发明内容
本申请实施例提供一种应用程序的资源更新方法、装置、设备、计算机可读存储介质及计算机程序产品,能够在应用程序运行中,实现应用程序的更新,提高应用程序的更新效率。
本申请实施例的技术方案是这样实现的:
本申请实施例提供一种应用程序的资源更新方法,包括:
在应用程序运行过程中,获取所述应用程序的更新资源包,所述更新资源包中包括更新资源及可执行文件;
基于所述可执行文件,创建所述更新资源包对应的插件类加载器,并生成包括至少一个非插件类加载器的类加载器集合;
在所述应用程序对应的类加载器链中,获取宿主类加载器,并将所述宿主类加载器的父类加载器替换为所述插件类加载器,得到目标类加载器链;
基于所述类加载器集合、所述目标类加载器链中至少之一,确定用于加载所述更新资源归属的目标类的目标类加载器;
通过所述目标类加载器加载所述目标类,并基于所述更新资源,运行所述目标类对应的功能。
本申请实施例提供一种应用程序的资源更新装置,包括:
获取模块,用于在应用程序运行过程中,获取所述应用程序的更新资源包,所述更新资源包中包括更新资源及可执行文件;
生成模块,用于基于所述可执行文件,创建所述更新资源包对应的插件类加载器,并生成包括至少一个非插件类加载器的类加载器集合;
替换模块,用于在所述应用程序对应的类加载器链中,获取宿主类加载器,并将所述宿主类加载器的父类加载器替换为所述插件类加载器,得到目标类加载器链;
查找模块,用于基于所述类加载器集合、所述目标类加载器链中至少之一,确定用于加载所述更新资源归属的目标类的目标类加载器;
运行模块,用于通过所述目标类加载器加载所述目标类,并基于所述更新资源,运行所述目标类对应的功能。
上述方案中,所述查找模块,还用于基于所述目标类加载器链中各节点对应的类加载器,确定用于加载所述更新资源归属的目标类的目标类加载器;
当基于所述目标类加载器链未能确定所述目标类加载器时,基于所述类加载器集合中的各类加载器,确定所述目标类加载器;
其中,所述目标类加载器链中的类加载器具有层级关系,所述类加载器集合中的类加载器不具有层级关系。
上述方案中,所述查找模块,还用于基于所述目标类加载器链中各类加载器之间的层级关系,确定以所述插件类加载器为最低层级的子层级关系;
从所述插件类加载器开始,获取所述子层级关系中各层级的类加载器的类加载路径;
获取所述目标类的目标类加载路径,并将所述目标类加载路径与各所述类加载路径进行比对,得到比对结果;
当所述比对结果表征所述目标类加载路径与任一所述类加载路径不同时,将所述插件类加载器作为所述目标类的目标类加载器。
上述方案中,所述查找模块,还用于获取所述类加载器集合中各类加载器的类加载路径;
获取所述目标类的目标类加载路径,并在所述各类加载器的类加载路径中查找所述目标类加载路径,得到查找结果;
当所述查找结果表征所述各类加载器的类加载路径中存在所述目标类加载路径时,将所述类加载路径所归属的类加载器,作为所述目标类加载器。
上述方案中,所述查找模块,还用于识别所述更新资源归属的目标类的类型,所述类型包括宿主类、插件类;
其中,所述宿主类为,在安装所述应用程序时,通过宿主类加载器所加载的类,所述插件类为,在运行所述应用程序时,通过插件类加载器所加载的类;
上述方案中,所述查找模块,还用于当所述类型为宿主类时,从所述类加载器集合中的至少一个非插件类加载器中,确定用于加载所述目标类的目标类加载器;
当所述类型为插件类时,获取所述插件类加载器对应的引用类标识集合,并基于所述类加载器集合和所述目标类加载器链中之一、及所述引用类标识集合,确定用于加载所述目标类的目标类加载器;
其中,所述引用类标识为,所述插件类加载器中所引用的其他类的类标识。
上述方案中,所述查找模块,还用于将所述目标类的类标识与所述引用类标识集合中的各类标识进行匹配,得到匹配结果;
当所述匹配结果表征所述目标类的类标识属于所述引用类标识集合时,基于所述类加载器集合,确定用于加载所述目标类的目标类加载器;
当所述匹配结果表征所述目标类的类标识不属于所述引用类标识集合时,基于所述目标类加载器链,确定用于加载所述目标类的目标类加载器。
上述方案中,所述运行模块,还用于获取所述更新资源的资源加载路径,及所述应用程序的资源加载器;
在所述资源加载器中所述应用程序的原始资源加载路径之前,***所述资源加载路径,得到目标资源加载路径;
根据所述目标资源加载路径所指示的加载顺序,将所述更新资源加载至所述应用程序的内存空间。
上述方案中,所述运行模块,还用于当基于所述类加载器集合、所述目标类加载器链中至少之一,能够确定所述目标类的目标类加载器时,获取所述目标类的类加载路径,并控制所述目标类加载器,基于所述类加载路径执行针对所述目标类的加载操作;
在执行所述加载操作的过程中,基于所述更新资源的资源标识,从所述应用程序的内存空间中,获取所述更新资源,并当所述加载操作完成时,基于所述更新资源,运行资源更新后的所述目标类对应的功能。
上述方案中,所述运行模块,还用于当基于所述类加载器集合、所述目标类加载器链中至少之一,不能确定所述目标类的目标类加载器时,控制所述插件类加载器捕获异常信息,并基于所述异常信息,生成错误提示信息;
当运行所述目标类对应的功能时,展示所述错误提示信息;
其中,所述错误提示信息,用于表征基于所述更新资源包针对所述应用程序的更新操作失败。
上述方案中,所述获取模块,还用于在应用程序运行过程中,接收到服务器下发的更新通知,所述更新通知用于指示所述应用程序存在更新资源包;
依据所述更新通知,下载所述更新资源包至本地存储空间,并通知所述应用程序的进程,以使所述进程从所述本地存储空间中,获取所述更新资源包。
上述方案中,所述生成模块,还用于解析所述可执行文件,得到所述更新资源包所包括的至少一个待加载类;
创建用于加载所述至少一个待加载类的插件类加载器;
所述生成包括至少一个非插件类加载器的类加载器集合,包括:
获取所述应用程序对应的至少一个非插件类加载器,并生成包括至少一个非插件类加载器、及除所述插件类加载器之外的其他插件类加载器的类加载器集合。
本申请实施例提供一种电子设备,包括:
存储器,用于存储可执行指令;
处理器,用于执行所述存储器中存储的可执行指令时,实现本申请实施例提供的应用程序的资源更新方法。
本申请实施例提供一种计算机可读存储介质,存储有可执行指令,用于引起处理器执行时,实现本申请实施例提供的应用程序的资源更新方法。
本申请实施例提供一种计算机程序产品,包括计算机程序或指令,用于引起处理器执行时,实现本申请实施例提供的应用程序的资源更新方法。
本申请实施例具有以下有益效果:
应用本申请实施例,在应用程序运行过程中,获取针对应用程序的更新资源包,并创建更新资源包对应的插件类加载器,然后将宿主类加载在应用程序的类加载器链中的父类加载器替换为插件类加载器,得到目标类加载器链,如此,能够保证在进行资源更新时,优先使用插件类加载器加载更新资源归属的目标类;同时,结合目标类加载器链及类加载器集合确定目标类加载器,能够保证确定目标类加载器的准确性,提高目标类加载器的查找效率;采用目标类加载器加载目标类,运行与更新资源相关联的功能,如此,能够在程序运行中,实现应用程序的更新,提高应用程序的更新效率。
附图说明
图1是本申请实施例提供的应用程序的资源更新***的架构示意图;
图2是本申请实施例提供的应用程序的资源更新的电子设备500的结构示意图;
图3是本申请实施例提供的应用程序的资源更新方法的流程示意图;
图4是本申请实施例提供的目标类加载器的确定方式;
图5是本申请实施例提供的基于目标类加载器链确定目标类加载器的方法流程图;
图6是本申请实施例提供的基于类加载器集合确定目标类加载器的方法流程图;
图7是本申请实施例提供的基于目标类的类型确定目标类加载器的方法流程图;
图8是本申请实施例提供的更新资源的资源加载方法流程图;
图9是本申请实施例提供的目标类及更新资源的加载方法流程图;
图10是本申请实施例提供的获取应用程序的更新资源包的方法流程图;
图11是本申请实施例提供的获取应用程序的更新资源包的方法流程图;
图12是相关技术中提供的针对更新资源进行加载的流程示意图;
图13是本申请实施例提供的针对更新资源进行加载的流程示意图;
图14是相关技术中提供的资源加载引用的方式流程图;
图15是本申请实施例提供的资源加载引用的方式流程图;
图16是本申请实施例提供的动态加载类的方法流程图;
图17是相关技术中提供的类加载方式流程图;
图18是本申请实施例提供的针对更新资源包所引用的类的加载方式流程图;
图19是本申请实施例提供的基于多个更新资源包动态加载类的方法示意图。
具体实施方式
为了使本申请的目的、技术方案和优点更加清楚,下面将结合附图对本申请作进一步地详细描述,所描述的实施例不应视为对本申请的限制,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其它实施例,都属于本申请保护的范围。
在以下的描述中,涉及到“一些实施例”,其描述了所有可能实施例的子集,但是可以理解,“一些实施例”可以是所有可能实施例的相同子集或不同子集,并且可以在不冲突的情况下相互结合。
如果申请文件中出现“第一/第二”的类似描述则增加以下的说明,在以下的描述中,所涉及的术语“第一\第二\第三”仅仅是是区别类似的对象,不代表针对对象的特定排序,可以理解地,“第一\第二\第三”在允许的情况下可以互换特定的顺序或先后次序,以使这里描述的本申请实施例能够以除了在这里图示或描述的以外的顺序实施。
除非另有定义,本文所使用的所有的技术和科学术语与属于本申请的技术领域的技术人员通常理解的含义相同。本文中所使用的术语只是为了描述本申请实施例的目的,不是旨在限制本申请。
对本申请实施例进行进一步详细说明之前,对本申请实施例中涉及的名词和术语进行说明,本申请实施例中涉及的名词和术语适用于如下的解释。
1)补丁包:用于修复应用程序中漏洞或错误的文件,通常情况下,补丁包的大小远小于应用程序安卓安装包(APK,安卓Package)的大小。现有的补丁包方案都是基于函数替换或函数hook(钩子),通常用于对应用程序中的少量函数方法进行逻辑修改,并且在进行修改时,不允许对函数方法名、参数个数及顺序进行修改。
2)Dex(Dalvik执行,Dalvik VM execute)文件:安卓平台上的可执行文件,文件后缀名为.dex。通常情况下,应用程序APK中包含一个Dex文件,该Dex文件中包含应用程序对应的所有类,且每个类中包含各自对应的函数方法,用于实现应用程序的各种功能。
3)双亲委派机制:如果一个类加载器收到了类加载请求,它并不会自己先加载,而是把这个请求委托给父类的加载器去执行;如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的引导类加载器;如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成加载任务,子加载器才会尝试自己去加载,这就是双亲委派机制;父类加载器一层一层往下分配任务,如果子类加载器能加载,则加载此类,如果将加载任务分配至***类加载器也无法加载此类,则抛出异常。
4)插件化:一种免安装的安卓终端的app压缩包,通常有dex,apk,zip等格式
5)热部署:一种新的代码修改特性在进程无需重启的情况下就能动态的加载到进程内存中并能正常运行,以此替换掉原来的旧的代码特性
6)安卓资源:安卓apk包含代码dex,动态链接库so,安卓资源,配置文件这几部分,安卓资源包含了图片资源,资源配置文件等内容。
基于上述对本申请实施例中涉及的名词和术语的解释,下面说明本申请实施例提供的应用程序的资源更新***。参见图1,图1是本申请实施例提供的应用程序的资源更新***的架构示意图,为实现支撑一个示例性应用,终端(示例性示出了终端400-1和终端400-2)通过网络300连接服务器200,网络300可以是广域网或者局域网,又或者是二者的组合,使用无线或有线链路实现数据传输。
终端(如终端400-1和终端400-2),安装和运行有应用程序的客户端,用于在应用程序运行过程中,接收到服务器下发的更新通知,从服务器下载应用程序对应的更新资源包,并存储到本地存储空间(如移动终端的SD卡),并通知应用程序的进程,以使进程从本地存储空间中获取更新资源包。
终端(如终端400-1和终端400-2),还用于在应用程序运行过程中,获取应用程序的更新资源包,更新资源包中包括更新资源及可执行文件;基于可执行文件,创建更新资源包对应的插件类加载器,并生成包括至少一个非插件类加载器的类加载器集合;在应用程序对应的类加载器链中,获取宿主类加载器,并将宿主类加载器的父类加载器替换为插件类加载器,得到目标类加载器链;基于类加载器集合、目标类加载器链中至少之一,确定用于加载更新资源归属的目标类的目标类加载器;通过目标类加载器加载所述目标类,并基于更新资源,运行目标类对应的功能。
服务器200,用于在应用程序运行过程中,接收开发端上传的应用程序的更新资源包,向安装有该应用程序的终端下发更新通知,以通知各终端该应用程序存在更新资源包;同时,还用于接收终端发送的针对应用程序更新资源包的下载请求,将更新资源包发送至发送下载请求的终端(如终端400-1和终端400-2)。
在一些实施例中,服务器200可以是独立的物理服务器,也可以是多个物理服务器构成的服务器集群或者分布式***,还可以是提供云服务、云数据库、云计算、云函数、云存储、网络服务、云通信、中间件服务、域名服务、安全服务、内容分发网络(CDN,ContentDelivery Network)、以及大数据和人工智能平台等基础云计算服务的云服务器。终端400可以是智能手机、平板电脑、笔记本电脑、台式计算机、智能音箱、智能手表等,但并不局限于此。终端以及服务器可以通过有线或无线通信方式进行直接或间接地连接,本申请实施例中不做限制。
本申请实施例可以借助于云技术(Cloud Technology)实现,云技术是指在广域网或局域网内将硬件、软件、网络等系列资源统一起来,实现数据的计算、储存、处理和共享的一种托管技术。
云技术是基于云计算商业模式应用的网络技术、信息技术、整合技术、管理平台技术、以及应用技术等的总称,可以组成资源池,按需所用,灵活便利。云计算技术将变成重要支撑。技术网络***的后台服务需要大量的计算、存储资源。伴随着互联网行业的高度发展和应用,将来每个物品都有可能存在自己的识别标志,都需要传输到后台***进行逻辑处理,不同程度级别的数据将会分开处理,各类行业数据皆需要强大的***后盾支撑,可以通过云计算来实现。
参见图2,图2是本申请实施例提供的应用程序的资源更新的电子设备500的结构示意图。在实际应用中,电子设备500可以为图1示出的服务器或终端,以电子设备500为图1示出的域名解析节点为例,对实施本申请实施例的应用程序的资源更新的电子设备进行说明,本申请实施例提供的电子设备500包括:至少一个处理器510、存储器550、至少一个网络接口520和用户接口530。电子设备500中的各个组件通过总线***540耦合在一起。可理解,总线***540用于实现这些组件之间的连接通信。总线***540除包括数据总线之外,还包括电源总线、控制总线和状态信号总线。但是为了清楚说明起见,在图2中将各种总线都标为总线***540。
处理器510可以是一种集成电路芯片,具有信号的处理能力,例如通用处理器、数字信号处理器(DSP,Digital Signal Processor),或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等,其中,通用处理器可以是微处理器或者任何常规的处理器等。
用户接口530包括使得能够呈现媒体内容的一个或多个输出装置531,包括一个或多个扬声器和/或一个或多个视觉显示屏。用户接口530还包括一个或多个输入装置532,包括有助于用户输入的用户接口部件,比如键盘、鼠标、麦克风、触屏显示屏、摄像头、其他输入按钮和控件。
存储器550可以是可移除的,不可移除的或其组合。示例性的硬件设备包括固态存储器,硬盘驱动器,光盘驱动器等。存储器550可选地包括在物理位置上远离处理器510的一个或多个存储设备。
存储器550包括易失性存储器或非易失性存储器,也可包括易失性和非易失性存储器两者。非易失性存储器可以是只读存储器(ROM,Read Only Memory),易失性存储器可以是随机存取存储器(RAM,Random Access Memory)。本申请实施例描述的存储器550旨在包括任意适合类型的存储器。
在一些实施例中,存储器550能够存储数据以支持各种操作,这些数据的示例包括程序、模块和数据结构或者其子集或超集,下面示例性说明。
操作***551,包括用于处理各种基本***服务和执行硬件相关任务的***程序,例如框架层、核心库层、驱动层等,用于实现各种基础业务以及处理基于硬件的任务;
网络通信模块552,用于经由一个或多个(有线或无线)网络接口520到达其他计算设备,示例性的网络接口520包括:蓝牙、无线相容性认证(WiFi)、和通用串行总线(USB,Universal Serial Bus)等;
呈现模块553,用于经由一个或多个与用户接口530相关联的输出装置531(例如,显示屏、扬声器等)使得能够呈现信息(例如,用于操作***设备和显示内容和信息的用户接口);
输入处理模块554,用于对一个或多个来自一个或多个输入装置532之一的一个或多个用户输入或互动进行检测以及翻译所检测的输入或互动。
在一些实施例中,本申请实施例提供的应用程序的资源更新装置可以采用软件方式实现,图2示出了存储在存储器550中的应用程序的资源更新装置555,其可以是程序和插件等形式的软件,包括以下软件模块:获取模块5551、生成模块5552、替换模块5553、查找模块5554和运行模块,这些模块是逻辑上的,因此根据所实现的功能可以进行任意的组合或进一步拆分,将在下文中说明各个模块的功能。
在另一些实施例中,本申请实施例提供的应用程序的资源更新装置可以采用软硬件结合的方式实现,作为示例,本申请实施例提供的应用程序的资源更新装置可以是采用硬件译码处理器形式的处理器,其被编程以执行本申请实施例提供的应用程序的资源更新,例如,硬件译码处理器形式的处理器可以采用一个或多个应用专用集成电路(ASIC,Application Specific Integrated Circuit)、DSP、可编程逻辑器件(PLD,ProgrammableLogic Device)、复杂可编程逻辑器件(CPLD,Complex Programmable Logic Device)、现场可编程门阵列(FPGA,Field-Programmable Gate Array)或其他电子元件。
基于上述对本申请实施例提供的应用程序的资源更新***及电子设备的说明,下面说明本申请实施例提供的应用程序的资源更新方法。在一些实施例中,本申请实施例提供的应用程序的资源更新方法可由服务器或终端单独实施,或由服务器及终端协同实施,下面以终端实施为例说明本申请实施例提供的应用程序的资源更新方法。
参见图3,图3是本申请实施例提供的应用程序的资源更新方法的流程示意图,本申请实施例提供的应用程序的资源更新方法包括:
在步骤101中,终端在应用程序运行过程中,获取应用程序的更新资源包,更新资源包中包括更新资源及可执行文件。
在实际实施时,应用程序可以是基于安卓***(即终端的***为安卓***)的安卓桌面应用,终端上部署有应用程序,在应用程序的运行过程中,终端可以通过网络下载等方式获取应用程序对应的更新资源包(也可称为插件包、补丁包等)实现针对应用程序的热部署。针对应用程序热部署方式包括代码修复、资源修复等。其中,代码修复的原理是类的替换,可以理解成为使用更新资源包中的类更新应用程序中的类,这里的更新可以包括使用更新资源包中的类替换应用程序中已加载的类,还可以包括在应用程序中新增更新资源包中的类。类的替换主要是由类加载器(classloader)的使用,基于类加载器实现代码的动态加载。获取的更新资源包采用apk格式,更新资源包中包含可执行文件,终端中的安卓虚拟机通过dex文件动态加载更新资源包中的各种类(代码的动态加载)。
在步骤102中,基于可执行文件,创建更新资源包对应的插件类加载器,并生成包括至少一个非插件类加载器的类加载器集合。
在实际实施时,终端的虚拟机解析更新资源包中的可执行文件(如安卓***的dex文件),创建用于动态加载可执行文件的代码(代码中包括实现应用程序的更新所包括的所有类)的类加载器(即插件类加载器)。同时,生成与非插件类加载器对应的类加载器集合,类加载器集合中包括一个或多个非插件类加载器、还可以包括其他插件类的插件类加载器。需要说明的是,类加载器集合中的各类加载器是相互独立的,不具有层次关系。
示例性地,以应用程序为基于安卓应用为例、执行文件为dex文件为例,dex文件中包括更新资源包的所有类,且每个类中包含各自对应的函数方法,用于实现应用程序的各种功能。
在步骤103中,在应用程序对应的类加载器链中,获取宿主类加载器,并将宿主类加载器的父类加载器替换为插件类加载器,得到目标类加载器链。
在实际实施时,由于终端中针对类的加载是基于双亲委派机制实现的。即通过类加载器加载类时,存在一个具有层级关系的类加载器链,宿主类加载器是该类加载器链上的一个节点,当基于宿主类加载器进行类加载时,会先委托给宿主类加载器的父类加载器进行加载(基于双亲委派机制的类加载过程,同一个类不会重复加载,即每个类只加载一次),为了优先对更新资源包进行加载,可以直接将用于加载更新资源包中类的插件类加载器作为宿主类加载器的父(类)加载器。如此,运行至更新资源包对应的功能时,会优先使用插件类加载器进行加载。
首先,获取正在运行的应用程序的类加载器(即宿主类加载器)、及宿主类加载器所处的类加载器链。类加载器链是由多个类加载器构成,相邻类加载器之间为父子关系,各类加载器用于实现对不同类型的类的加载。实现过程可以是调用安卓***提供的类的getClassLoader方法得到正在运行的应用程序的类加载器(宿主类加载器),再调用***类加载器提供的getParent方法,得到宿主类加载器的父(类)加载器、以及包含宿主类加载器的类加载器链,类加载器链中的各类加载器存在层级关系,其中,最顶层的为***类加载器。
示例性地,以安卓***中加载更新资源包为例,用于加载应用程序的类的类加载器链为BaseClassLoader(应用类加载器)->BootClassLoader(启动类加载器),即BaseClassLoader的父类加载器为BootClassLoader。以java***中加载更新资源包为例,用于加载应用程序的类的类加载器链为UserClassLoader(用户自定义类加载器)->Application ClassLoader(应用程序类加载器)->ExtentionClassLoader(扩展类加载器)->BootstrapClassLoader(启动类加载器)。
在步骤104中,基于类加载器集合、目标类加载器链中至少之一,确定用于加载更新资源归属的目标类的目标类加载器。
在实际实施时,根据类加载器的双亲委派机制,***优先使用宿主加载器属类加载器链中父一级的类加载器进行类加载的原理。如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成加载任务,子加载器才会尝试自己去加载,父类加载器一层一层往下分配任务,如果子类加载器能加载,则加载此类,如果将加载任务分配至***类加载器也无法加载此类,则抛出异常(应用程序的某一功能在使用该功能时出现异常、崩溃等场)。基于此,为了保证程序的正常运行,可以在插件类加载器对应的类加载器集合中查找用于加载更新资源包中类的类加载器,以避免应用程序运行至相应功能时出现崩溃情况。
在一些实施例中,参见图4,图4是本申请实施例提供的目标类加载器的确定方式,基于图3,步骤104可以通过步骤1041-1042实现:
步骤1041,终端基于目标类加载器链中各节点对应的类加载器,确定用于加载更新资源归属的目标类的目标类加载器。
其中,目标类加载器链中的类加载器具有层级关系。
在实际实施时,针对类的加载过程是基于双亲委派机制,目标类加载器链中宿主类加载器的父类加载器为更新资源包对应的插件类加载器,应用程序运行过程中,宿主加载器接收到针对更新资源包中所使用的至少一个类的类加载请求时,优先委托给插件类加载器执行,如果插件类加载器在目标加载器链中还存在父类加载器,进一步向上委托,依次递归,直至请求达到最顶层的引导类加载器,如果父类加载器可以完成类加载任务,就成功返回,此时,该父类加载器即为加载更新资源归属的目标类的目标类加载器。
在一些实施例中,参见图5,图5是本申请实施例提供的基于目标类加载器链确定目标类加载器的方法流程图,结合图5示出的步骤201a-204a进行说明:
步骤201a,基于目标类加载器链中各类加载器之间的层级关系,确定以插件类加载器为最低层级的子层级关系。
在实际实施时,目标类加载器链中的各类加载器存在层级关系,即插件类加载器的子类为宿主类加载器,确定以插件类加载器为最次层级的子层级关系,如此,宿主类加载器接收到针对更新资源包中包含的类的类加载请求时,会直接将该类加载请求委托给子层级关系中插件类加载器执行,插件类加载器基于双亲委派机制,确定更新资源包中各类的类加载器。
步骤202a,从插件类加载器开始,获取子层级关系中各层级的类加载器的类加载路径。
在实际实施时,每个类加载器都对应有可以加载的类加载路径,用于表征当前类加载器能够加载的类的类路径。终端解析更新程序包中可执行文件,确定更新资源包中所应用的类的类加载路径,并与子层级关系中各层级的类加载器的类加载路径进行匹配,如此,可以确定更新资源包所引用的类所对应的类加载器。
步骤203a,获取目标类的目标类加载路径,并将目标类加载路径与各类加载路径进行比对,得到比对结果。
在实际实施时,待加载类的类路径,与类加载器中的至少一个类加载路径进行匹配,当匹配成功时,可以表征该待加载类已经被当前类加载器加载过了,在应用程序不重启的情况下,该待加载类将不会再次被加载。
步骤204a,当比对结果表征目标类加载路径与任一类加载路径不同时,将插件类加载器作为目标类的目标类加载器。
在实际实施时,将目标类加载路径与子层级关系中所包括各类加载器对应的类加载路径相比对,当目标类加载路径与任一类加载路径不同时,说明,该目标类在当前运行的应用程序中,没有被加载过,此时,将插件类加载器作为目标类的类加载器,用于对目标类进行加载。
步骤1042,当基于目标类加载器链未能确定目标类加载器时,基于类加载器集合中的各类加载器,确定目标类加载器。
其中,类加载器集合中的类加载器不具有层级关系。
在实际实施时,当插件类加载器作为目标类的目标类加载器时,如果插件类加载器不能加载该目标类,则说明目标类为其他更新包资源中的类、或为应用程序中已安装的类。为了避免程序崩溃,可以在插件类加载器对应的类加载器集合中,查找用于加载目标类的类加载器。插件类加载器对应的类加载器集合包括除自身之外的宿主类加载器、及其他类加载器。需要说明的是,类加载器集合中的宿主类加载器是用于优先加载更新资源包中的相关类的。如此,能够有效避免类不会被加载到的问题。
在一些实施例中,参见图6,图6是本申请实施例提供的基于类加载器集合确定目标类加载器的方法流程图,结合图6示出的步骤201b-203b进行说明:
步骤201b,终端获取类加载器集合中各类加载器的类加载路径。
在实际实施时,当基于目标类加载器链中的各类加载器,未能确定目标类加载器时,可以继续基于类加载器集合对目标类加载器集合进行查找。类加载器集合的作用为,当基于双亲委派机制在目标类加载器链中无法确定目标类加载器时,可继续在类加载器集合中对目标类加载器进行二次查找,从而确定目标类加载,实现对目标类的加载,避免应用程序运行过程中出现崩溃等情况。因此,终端获取类加载器集合中各类加载器所能加载的类加载路径,以完成基于类加载路径的查找过程。
步骤202b,获取目标类的目标类加载路径,并在各类加载器的类加载路径中查找目标类加载路径,得到查找结果。
在实际实施时,终端获取类加载器集合中各类加载器的类加载路径,并在各类加载路径中查找目标类加载路径。
步骤203b,当查找结果表征各类加载器的类加载路径中存在目标类加载路径时,将类加载路径所归属的类加载器,作为目标类加载器。
在实际实施时,目标类的类加载路径与类加载器集合中各类加载器对应的类加载路径进行匹配,将与目标类加载路径相同的类加载路径所对应的类加载器作为目标类加载器,需要说明的是,类加载路径中可以包括类名称、类标识等信息,若目标类的类名称与当前类加载路径中的类名称相同,不能说明目标类的类加载类路径与当前类加载路径相匹配。
在一些实施例中,参见图7,图7是本申请实施例提供的基于目标类的类型确定目标类加载器的方法流程图,基于图3,步骤104可以通过步骤1041b-1044b实现:
步骤1041b,终端识别更新资源归属的目标类的类型,类型包括宿主类、插件类。
其中,宿主类为,在安装应用程序时,通过宿主类加载器所加载的类,插件类为,在运行应用程序时,通过插件类加载器所加载的类。
在实际实施时,为了提高针对目标类加载器的查找效率,可以先是被目标类的类型,并根据类型判断是采用目标类加载器链确定目标类加载器还是采用类加载器集合确定目标类加载器,如此,不需要进行二次查找,能够有效提高确定目标类加载器的效率。需要说明的是,类的类型可分为宿主类以及插件类。其中,宿主类可以理解为应用程序安装时,宿主类加载器所加载的类,插件类可理解为在应用程序运行时,通过插件类加载器所加载的类。
步骤1042b,当类型为宿主类时,从类加载器集合中的至少一个非插件类加载器中,确定用于加载目标类的目标类加载器。
在实际实施时,类型为宿主类时,则直接可以在插件类加载器对应的类加载器集合中确定目标类加载器。如此,可以不用在目标类加载器链中的各类加载器中查找,有效提高了查找效率。
步骤1043b,当类型为插件类时,获取插件类加载器对应的引用类标识集合,其中,引用类标识为,插件类加载器中所引用的其他类的类标识。
在实际实施时,类型为插件类时,还需要进一步根据目标类的类标识,确定目标类加载器。即终端根据目标类的类标识进一步判断是基于插件类加载器所在的目标类加载器链确定目标类加载器,还是使用类加载器集合中的其他插件类加载器确定目标类加载器。
步骤1044b,基于类加载器集合和目标类加载器链中之一、及引用类标识集合,确定用于加载目标类的目标类加载器。
在实际实施时,根据引用类标识集合中引用类标识,从类加载器集合或目标类加载器链中,确定目标类加载器。
在一些实施例中,终端可以通过以下方式实现基于目标类的类型确定目标类加载器:终端将目标类的类标识与引用类标识集合中的各类标识进行匹配,得到匹配结果;当匹配结果表征目标类的类标识属于引用类标识集合时,基于类加载器集合,确定用于加载目标类的目标类加载器;当匹配结果表征目标类的类标识不属于引用类标识集合时,基于目标类加载器链,确定用于加载目标类的目标类加载器。
在实际实施时,首先将目标类的类标识与引用类标识集合中的各类标识进行匹配,若能够在引用类标识集合中找到目标类的类标识,表征该目标类是基于可执行文件解析得到的类的引用类,不能通过插件类加载器进行加载,因此,基于插件类加载器对应的类加载器集合,确定用于加载目标类的目标类加载器;若未能在引用类标识集合中找到目标类的类标识,表征该目标类不是引用类,则可以基于插件类加载器所对应的目标类加载器链中,确定目标类加载器。
在步骤105中,通过目标类加载器加载目标类,并基于更新资源,运行目标类对应的功能。
在实际实施时,通过采用双亲委派机制的目标类加载器链、及插件类加载器对应的类加载器集合,确定加载更新资源对应的类的目标类加载器,并基于目标类加载器对更新资源对应的类进行加载,实现针对应用程序的代码的热修复操作。并基于应用程序对应的资源管理器,将更新资源加载至终端为应用程序所分配的内存,以实现针对应用程序的资源的热部署。可以理解的是,基于更新资源包,实现针对应用程序的热更新或热部署,应用程序的服务器下发一个插件资源包,终端下载到该资源包后,通过广播的方式通知应用程序的应用进程,应用进程收到广播通知后通过类加载器加载对应的资源包,具体步骤如下:终端把更新资源包拷贝到为应用程序分配的指定的插件安装目录;通过反射资源管理器的添加资源方法加载更新资源包;通过类加载时所采用的双亲委派机制(即目标类加载器链)、自定义类加载器列表(即类加载器集合)的方式加载更新资源对应的类;通过调整宿主类加载器所在双亲委派链节点(类加载器链)的方式在应用程序运行期间动态替换宿主类加载器的父节点,即将宿主类加载器父类替换为插件类加载器,从而完成应用程序的更新资源包的自动生效,整个更新过程无需重启应用程序的进程。
在一些实施例中,参见图8,图8是本申请实施例提供的更新资源的资源加载方法流程图,基于图3,在步骤105之后,还可以执行:
步骤301,终端获取更新资源的资源加载路径,及应用程序的资源加载器。
在实际实施时,终端获取到更新资源包后,获取更新资源包中更新资源的资源加载路径,该更新资源即需要在应用程序中增加或进行替换的资源。
示例性地,以安卓***为例,安卓资源的加载采用的资源管理器AssetManager来加载,然后在类中是通过资源标识来引用资源并解析使用的。
步骤302,在资源加载器中应用程序的原始资源加载路径之前,***资源加载路径,得到目标资源加载路径。
在实际实施时,为了能够优先加载到更新资源,可以在资源加载器中应用程序的原始资源加载路径之前,***资源加载路径。如此,能够保证
步骤303,根据目标资源加载路径所指示的加载顺序,将更新资源加载至应用程序的内存空间。
在实际实施时,与类加载相似的,安卓虚拟机根据修改后的资源加载路径所指示的加载顺序(先更新资源,后原始应用程序对应的资源),进行资源加载,从而实现在原始应用程序中增加资源,或,替换原始应用程序中的资源。
上述方式,通过在原始应用程序的资源加载路径之前***更新资源的资源加载路径,使得***虚拟机进行资源加载时,优先对更新资源包中的更新资源进行加载,从而实现向原始应用程序中增加资源或替换原始应用程序中的资源。
在一些实施例中,参见图9,图9是本申请实施例提供的目标类及更新资源的加载方法流程图,基于图3,在步骤105之后,还可以执行:
步骤401,终端当基于类加载器集合、目标类加载器链中至少之一,能够确定目标类的目标类加载器时,获取目标类的类加载路径。
在实际实施时,确定目标类的目标类加载器之后,通过确定目标类的类加载路径,实现对目标类的加载操作。
步骤402,控制目标类加载器,基于类加载路径执行针对目标类的加载操作。
在实际实施时,终端控制目标类加载器,将目标类的类加载路径作为参数,实现针对目标类的加载操作。
示例性地,在安卓***中,对目标类A的加载,安卓***调用目标类加载器classloader中的loadClass方法,实现针对目标类的加载。其中,loadClass方法的参数为目标类A的类加载路径。
步骤403,在执行加载操作的过程中,基于更新资源的资源标识,从应用程序的内存空间中,获取更新资源。
在实际实施时,在针对更新资源对应的类进行加载操作时,若类中有对资源的引用,则可根据更新资源的资源标识,从应用程序的内存空间中,获取更新资源。
步骤404,当加载操作完成时,基于更新资源,运行资源更新后的目标类对应的功能。
在实际实施时,终端控制应用程序的进程,根据可执行文件完整对更新资源包中各类的动态加载后,结合双亲委派机制使得在进行类加载时,优先加载更新资源包中的各类的情况下,同时,根据更新资源包中各更新资源的资源加载路径、以更新资源包中各类基于资源标识对各更新资源的引用情况,完成资源的更新,从而基于更新资源包完成针对应用程序的热部署。
在一些实施例中,当未确定目标类对应的目标类加载器时,终端还可以显示错误提示信息:当基于类加载器集合、目标类加载器链中至少之一,不能确定目标类的目标类加载器时,控制插件类加载器捕获异常信息,并基于异常信息,生成错误提示信息;当运行目标类对应的功能时,展示错误提示信息;其中,错误提示信息,用于表征基于更新资源包针对应用程序的更新操作失败。
在实际实施时,当目标类对应的类加载器即不能基于目标类加载器链确定,也不能基于类加载器集合确定时,更新资源包对应的插件类加载器会捕获相应的类未能加载成功或类加载器未能找到的异常信息,并采用可视化的方式展示错误提示信息。
示例性地,以安卓***为例,当插件类加载器捕捉到类未找到的异常,可以在展示应用程序的界面中弹出“功能A正在完善中”等错误提示信息。
在一些实施例中,参见图10,图10是本申请实施例提供的获取应用程序的更新资源包的方法流程图,基于图3,在步骤105之后,还可以执行:
步骤501,终端在应用程序运行过程中,接收到服务器下发的更新通知,更新通知用于指示应用程序存在更新资源包。
在实际实施时,应用程序在运行的过程中,可以实时接收服务器下发的更新通知。另外,应用程序还可以主动向服务器发送更新请求,以向服务器请求更新资源包。
示例性地,终端在运行应用程序A时,终端展示“当前应用有更新,是否更新”,当选择更新时,向服务器发送针对应用程序A的更新请求。
步骤502,依据更新通知,下载更新资源包至本地存储空间。
在实际实施时,终端根据接收到更新通知,从服务器下载应用程序的更新资源包至本地存储空间。如安卓终端将应用程序的更新包下载至本地存储卡。
步骤503,通知应用程序的进程,以使进程从本地存储空间中,获取更新资源包。
在实际实施时,终端将应用程序的更新资源包下载至本地后,通过控制应用程序运行的进程,从本地存储空间中,获取终端从服务器下载的更新资源包。
在一些实施例中,参见图11,图11是本申请实施例提供的获取应用程序的更新资源包的方法流程图,基于图3,在步骤105之后,还可以执行:
步骤601,终端解析可执行文件,得到更新资源包所包括的至少一个待加载类。
在实际实施时,针对运行的应用程序,一次更新可能是多个不同的功能模块进行更新,也即更新资源包中包括各个待加载类,其中一个待加载类可以表征一个功能模块,即一个功能模块对应一个待加载类。
示例性地,以安卓应用为例,在应用程序A的运行过程中,运行至功能B时,终端检测到服务器下发的针对功能B的更新资源包,安卓***解析更新资源包,得到待加载类a、待加载类b、及待加载类c,其中待加载类a引用待加载类b、及待加载类c,待加载类a、待加载类b、及待加载类c分别对应不同的功能。
步骤602,创建用于加载至少一个待加载类的插件类加载器。
在实际实施时,终端创建用于加载待加载类的插件类加载器,用于实现针对更新资源包中各类的加载操作。
承接上例,安卓***创建用于加载上述待加载类a、待加载类b、及待加载类c的插件类加载器1、插件类加载器2、插件类加载器3。
步骤603,获取应用程序对应的至少一个非插件类加载器,并生成包括至少一个非插件类加载器、及除插件类加载器之外的其他插件类加载器的类加载器集合。
承接上例,在对通过插件类加载器1对待加载类a进行加载时,会基于插件类加载器1确定待加载类a对应的目标类加载器链,同时生成插件类加载器1对应的类加载器集合S,S中包括除插件类加载器1之外的,其他应用程序运行时,所需要的所有类加载器,如插件类加载器2、插件类加载器3等,其中,各类加载器是相互独立且不具有层级关系。
应用本申请实施例,在应用程序运行过程中,创建更新资源包对应的插件类加载器,并将宿主类加载在应用程序的类加载器链中的父类加载器替换为插件类加载器,得到目标类加载器链,如此,能够保证在进行资源更新时,优先使用插件类加载器加载更新资源归属的目标类;同时,结合目标类加载器链及类加载器集合确定目标类加载器,能够保证确定目标类加载器的准确性,提高目标类加载器的查找效率;采用目标类加载器加载目标类,运行与更新资源相关联的功能,如此,能够在程序运行中,实现动态替换类加载器的方式实现动态替换资源标识,从而实现了应用进程无需重启就能实现资源的更新。
下面,将说明本申请实施例在一个实际的应用场景中的示例性应用。
安卓插件化中的资源动态化在业界中只有资源冷启动生效,例如业界现有的热修复,热更新方案都必须重启APP才能实现修复,热修复,热更新的“热”指的是不需要进行APP的整包升级,直接通过下发修复包然后重启APP即可实现bug修复,而我们的热部署的“热”指的是APP既不需要APP整包升级,也不需要进行APP重启就能实现修复;在资源动态化升级后必须把当前的进程杀死重启后才能让新的资源应用生效,而在移动终端刷脸支付过程中,由于是面向业务(ToB)的APP使用场景,app进程是24小时存在的,如果app由于资源动态化要进行重启那么对刷脸支付流程会有体验影响,例如进程重启需要重新初始化就会拖慢首次刷脸的速度,而且进程重启可能对商户支付收银产生打断的影响,让商户能感知到我们的刷脸应用在发生变更,会给商户造成困扰。
基于此,本申请实施例提供一种应用程序的更新方法,该针对这种特殊的业务场景下能够无需进程重启就能做到资源动态化生效的方案,也就是安卓终端资源级别的热部署生效方案。
接下来,对本申请实施例提供的应用程序的更新方法(即资源级别的热部署生效)进行具体阐述。
在实际实施时,安卓***中资源的加载采用的是资源管理器(AssetManag er)来加载,然后在代码(类)实现中是通过资源标识(用来表示资源的唯一性)来引用资源并解析使用的。因此,针对资源动态化更新(即资源热部署)一方面可以通过资源管理器来加载更新资源包的更新资源(如图片、文件、动画等)。另一方面,由于实现代码中字段热部署生效,除了把更新资源包加载到内存中还要动态的替换掉代码中对于旧的资源标识的引用,因此,在实际应用中,可以采用独立类加载器(插件类加载器)加载类的方式实现在代码中动态替换资源标识(即通过插件类加载器实现代码修复),通过以上两种方式的结合可以做到安卓资源的热部署生效。也就是说,实现本申请实施例提供的应用程序的更新方法,至少包括两个功能模块:1)基于资源管理器,对更新资源进行加载,即通过资源管理器将更新资源包中的资源加载到终端内存;2)基于独立类加载器,对更新资源包中的类进行加载,即通过独立类加载器动态替换掉更新资源包中代码所引用的资源标识。
接下来,基于资源管理器,对更新资源进行加载的过程进行说明。即通过资源管理器将更新资源包中的更新资源加载到终端内存。在实际实施时,参见图12,图12是相关技术中提供的针对更新资源进行加载的流程示意图,图中,加载更新资源的过程如下:终端执行步骤1.通过反射重新创建一个新的资源管理器AssetsManager对象,然后执行步骤2.通过反射调用AssetsManager资源加载接口,接着执行步骤3.通过调用AssetManager.addAssetPath方法,把相应的插件资源(即更新资源,如宿主apk的资源、分包apk的资源、插件apk资源)加载至存储空间;接着执行步骤4.判断资源包是否已经加载,若是则执行步骤4.1不重复加载,直接返回已加载的资源包索引,若否则执行步骤4.2加载成功,返回资源包索引,然后执行步骤5.分别反射ResourcesManager***类、反射LoadedApk类、反射Context***类,最后执行步骤6.分别更新ResourcesImpl中的Resources对象、更新LoadedApk中的Resources对象及更新Context中的Resources对象,也就是说,图11中是通过替换运行的应用程序中上下文Context、LoadedApk、ResourcesManager中维护的Resources对象来进行资源更新,这种方式并不能保证所有的Resources对象都被更新(即更新具有片面性),仅保证Context,LoadedApk,ResourcesManager这三个地方的Resources对象更新。
基于此,参见图13,图13是本申请实施例提供的针对更新资源进行加载的流程示意图。解析ResourcesManager类的源码,可以确定应用程序中所有的Resources对象都会保存在ResourcesManager中(如ResourcesImpl,ResourcesRef,ActivityResourcesRef),通过遍历Resources的这些属性,获取到所有的AssetsManager对象,然后再把更新资源通过AssetsManager的addAssetPath方法来添加插件资源。因此,基于图12中的资源加载方式进行修改,在图13中步骤1-4与图12中步骤一样,从步骤5开始,修改后的资源加载方式为终端执行步骤5.反射ResourcesManager***类,不需要反射其他的***类,如此,能减少***开销,提升性能,然后执行步骤6.获取所有的ResourcesManager对象,然后执行步骤7.调用AssetManager.addAssetPath方法加载所有ResourcesManager对象。
接下来,基于独立类加载器,对更新资源包中的类进行加载的过程进行说明。也就是说,基于独立类加载器动态替换掉代码中引用的资源标识。参见图14,图14是相关技术中提供的资源加载引用的方式流程图,图中,以安卓***中加载资源为例,安卓***中,通过步骤1.AssetManager加载资源,接着执行步骤2.调用应用类加载器BaseClassLoader加载类,然后执行步骤3.在类代码中寻找引用的资源标识(ID),找到资源标识后执行步骤4.根据资源标识在AssetManager中获取已经加载的资源,最后执行步骤5.解析资源并使用。在实际实施时,基于图14实现的资源加载引用的方式需要逐个替换资源标识,资源标识的粒度太小,针对***的计算资源消耗大、会导致其他功能的异常,也就是说,替换资源标识不具有可实现性,即使从类的粒度进行替换也是具有不可实现性。
基于此,参见图15,图15是本申请实施例提供的资源加载引用的方式流程图。该方式中,将动态替换类修改为动态替换类所在dex,利用安卓***提供的动态加载第三方dex方式实现动态替换dex,进而实现动态替换类(Class)、实现动态替换资源标识。图中,以安卓***中加载资源为例,安卓***中,通过步骤1.AssetManager加载资源,然后执行步骤2.调用第三方类加载器加载类,接着执行步骤3.判断类是否加载成功,若找不到类,进行降级加载,即执行步骤4.调用BaseClassLoader加载类,接着执行步骤5.从被替换的类中寻找资源标识;若步骤3判断加载成功,则执行步骤6.从新的类中寻找资源标识,最后基于步骤5或6找到目标资源标识,执行步骤7.根据资源标识在AssetManager中获取已经加载的资源。
在实际实施时,针对类的加载是采用双亲委派机制实现的,即在当前类加载器接收到针对类的类加载请求时,是先委托给自己的父类进行加载的,基于此,会了能够优先加载更新资源包对应的类,可以创建一个独立类加载器,并将该独立类加载器作为当前类加载器的父类加载器,具体的,参见图16,图16是本申请实施例提供的动态加载类的方法流程图,图中动态加载类的过程如下:***执行步骤1.启动应用程序,2.创建用于加载类的应用类加载器BaseClassLoader,3.通过BaseClassLoader加载应用程序中的类,在应用程序运行过程中,当动态加载新类时,执行步骤4.创建新的类加载器ClassLoader,执行步骤5.通过新的ClassLoader加载新的类,执行步骤6.确定BaseClassLoader的父节点(即父类加载器),然后执行步骤7.把BaseClassLoader的父节点设置为新创建的ClassLoader,接着执行步骤8.把原先BaseClassLoader的父节点设置为新创建ClassLoader的父节点。通过上述父类加载器的替换,实现类的动态加载,如此,能够保证总是优先加载更新资源包中的信息。
在实际实施时,参见图17,图17是相关技术中提供的类加载方式流程图,图中,针对采用双亲委派机制的类加载方式,图中,开始执行步骤1.应用类加载器BaseClassLoader接收到针对类的类加载请求时,执行步骤2.判断自身是否加载过此类,若有执行步骤5.指示类加载成功;若没有,则执行步骤3,委托给自身的父类加载器BootClassLoader(启动类对应的类加载器)进行加载,执行步骤4.判断BootClassLoader是否加载过此类,若有执行步骤5.指示类加载成功;若没有执行步骤6.指示Class加载失败应用程序对应的类加载器。在实际实施时,基于图17的方式,如果仅仅是双亲委派加载插件Class的话可以做到在宿主apk中加载插件类,但是无法在插件apk中加载宿主类,无法在插件apk中加载其他插件的类,因此会遇到ClassNotFoundException异常,自然也就无法做到热部署生效。基于此,参见图18,图18是本申请实施例提供的针对更新资源包所引用的类的加载方式流程图。图中,每一个第三方类加载器ClassLoader都作为双亲委派类加载器链中的一个节点,首先通过双亲委派模式去加载类,如果加载不到,会在第三方类加载器中保存一个类加载器集合(包括应用类加载器BaseClassLoader、第三方类加载器1、第三方类加载器2、),然后在第三方类加载器中捕获ClassNotFoundException,并且降级为去类加载器集合中去继续加载类,这样就可以做到宿主apk,插件apk可以任意加载对方的类;通过这种类加载机制我们做到了动态替换资源ID,而动态替换ClassLoader的parent的方式是不需要重启就能生效的,所以这里新的资源ID也就不需要重启就生效了,做到了资源ID的热部署生效,再结合AssetManager的addAssetPath接口来实现动态加载资源包到内存,整体上实现安卓资源热部署生效。
在实际实施时,当有多个更新资源包进行更新是,可以将用于加载待更新资源包的类加载器作为应用程序当前加载器的父(类)加载器。参见图19,图19是本申请实施例提供的基于多个更新资源包动态加载类的方法示意图,图中存在两个更新资源包对应的类加载器分别为第三方ClassLoader1、第三方ClassLoader2,先将BaseClassLoader的父类加载器替换为第三方ClassLoader1实现针对更新资源包1的部署,然后继续将BaseClassLoader的父类加载器替换为第三方ClassLoader2实现针对更新资源包2的部署。整个过程无需重启进程,只需要替换parent的ClassLoader即可实现资源更新生效。
上述实施例中,基于独立ClassLoader采用双亲委派加载和缓存列表ClassLoader的方式加载相结合的方式实现动态替换Dex的方式实现了动态替换资源ID,从而做到了进程无需重启就能实现安卓资源的热部署生效。
应用本申请实施例,当终端需要对安卓资源进行变更时,不需要对整包APK进行升级,直接下发一个需要更新的资源包(可包含图片,布局配置等),在终端下载资源包,然后通过如上方案去加载资源包即可做到终端的APP进程无需重启就可实现资源的动态更新。
可以理解的是,在本申请实施例中,涉及到用户信息等相关的数据,当本申请实施例运用到具体产品或技术中时,需要获得用户许可或者同意,且相关数据的收集、使用和处理需要遵守相关国家和地区的相关法律法规和标准。
下面继续说明本申请实施例提供的应用程序的资源更新装置555的实施为软件模块的示例性结构,在一些实施例中,如图2所示,存储在存储器550的应用程序的资源更新装置555中的软件模块可以包括:
获取模块5551,用于在应用程序运行过程中,获取所述应用程序的更新资源包,所述更新资源包中包括更新资源及可执行文件;
生成模块5552,用于基于所述可执行文件,创建所述更新资源包对应的插件类加载器,并生成包括至少一个非插件类加载器的类加载器集合;
替换模块5553,用于在所述应用程序对应的类加载器链中,获取宿主类加载器,并将所述宿主类加载器的父类加载器替换为所述插件类加载器,得到目标类加载器链;
查找模块5554,用于基于所述类加载器集合、所述目标类加载器链中至少之一,确定用于加载所述更新资源归属的目标类的目标类加载器;
运行模块5555,用于通过所述目标类加载器加载所述目标类,并基于所述更新资源,运行所述目标类对应的功能。
在一些实施例中,所述查找模块,还用于基于所述目标类加载器链中各节点对应的类加载器,确定用于加载所述更新资源归属的目标类的目标类加载器;当基于所述目标类加载器链未能确定所述目标类加载器时,基于所述类加载器集合中的各类加载器,确定所述目标类加载器;其中,所述目标类加载器链中的类加载器具有层级关系,所述类加载器集合中的类加载器不具有层级关系。
在一些实施例中,所述查找模块,还用于基于所述目标类加载器链中各类加载器之间的层级关系,确定以所述插件类加载器为最低层级的子层级关系;从所述插件类加载器开始,获取所述子层级关系中各层级的类加载器的类加载路径;获取所述目标类的目标类加载路径,并将所述目标类加载路径与各所述类加载路径进行比对,得到比对结果;当所述比对结果表征所述目标类加载路径与任一所述类加载路径不同时,将所述插件类加载器作为所述目标类的目标类加载器。
在一些实施例中,所述查找模块,还用于获取所述类加载器集合中各类加载器的类加载路径;获取所述目标类的目标类加载路径,并在所述各类加载器的类加载路径中查找所述目标类加载路径,得到查找结果;当所述查找结果表征所述各类加载器的类加载路径中存在所述目标类加载路径时,将所述类加载路径所归属的类加载器,作为所述目标类加载器。
在一些实施例中,所述查找模块,还用于识别所述更新资源归属的目标类的类型,所述类型包括宿主类、插件类;其中,所述宿主类为,在安装所述应用程序时,通过宿主类加载器所加载的类,所述插件类为,在运行所述应用程序时,通过插件类加载器所加载的类;
在一些实施例中,所述查找模块,还用于当所述类型为宿主类时,从所述类加载器集合中的至少一个非插件类加载器中,确定用于加载所述目标类的目标类加载器;当所述类型为插件类时,获取所述插件类加载器对应的引用类标识集合,并基于所述类加载器集合和所述目标类加载器链中之一、及所述引用类标识集合,确定用于加载所述目标类的目标类加载器;其中,所述引用类标识为,所述插件类加载器中所引用的其他类的类标识。
在一些实施例中,所述查找模块,还用于将所述目标类的类标识与所述引用类标识集合中的各类标识进行匹配,得到匹配结果;当所述匹配结果表征所述目标类的类标识属于所述引用类标识集合时,基于所述类加载器集合,确定用于加载所述目标类的目标类加载器;当所述匹配结果表征所述目标类的类标识不属于所述引用类标识集合时,基于所述目标类加载器链,确定用于加载所述目标类的目标类加载器。
在一些实施例中,所述运行模块,还用于获取所述更新资源的资源加载路径,及所述应用程序的资源加载器;在所述资源加载器中所述应用程序的原始资源加载路径之前,***所述资源加载路径,得到目标资源加载路径;根据所述目标资源加载路径所指示的加载顺序,将所述更新资源加载至所述应用程序的内存空间。
在一些实施例中,所述运行模块,还用于当基于所述类加载器集合、所述目标类加载器链中至少之一,能够确定所述目标类的目标类加载器时,获取所述目标类的类加载路径,并控制所述目标类加载器,基于所述类加载路径执行针对所述目标类的加载操作;在执行所述加载操作的过程中,基于所述更新资源的资源标识,从所述应用程序的内存空间中,获取所述更新资源,并当所述加载操作完成时,基于所述更新资源,运行资源更新后的所述目标类对应的功能。
在一些实施例中,所述运行模块,还用于当基于所述类加载器集合、所述目标类加载器链中至少之一,不能确定所述目标类的目标类加载器时,控制所述插件类加载器捕获异常信息,并基于所述异常信息,生成错误提示信息;当运行所述目标类对应的功能时,展示所述错误提示信息;其中,所述错误提示信息,用于表征基于所述更新资源包针对所述应用程序的更新操作失败。
在一些实施例中,所述获取模块,还用于在应用程序运行过程中,接收到服务器下发的更新通知,所述更新通知用于指示所述应用程序存在更新资源包;依据所述更新通知,下载所述更新资源包至本地存储空间,并通知所述应用程序的进程,以使所述进程从所述本地存储空间中,获取所述更新资源包。
在一些实施例中,所述生成模块,还用于解析所述可执行文件,得到所述更新资源包所包括的至少一个待加载类;创建用于加载所述至少一个待加载类的插件类加载器;获取所述应用程序对应的至少一个非插件类加载器,并生成包括至少一个非插件类加载器、及除所述插件类加载器之外的其他插件类加载器的类加载器集合。
本申请实施例提供了一种计算机程序产品或计算机程序,该计算机程序产品或计算机程序包括计算机指令,该计算机指令存储在计算机可读存储介质中。计算机设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算机设备执行本申请实施例上述的应用程序的资源更新方法。
本申请实施例提供一种存储有可执行指令的计算机可读存储介质,其中存储有可执行指令,当可执行指令被处理器执行时,将引起处理器执行本申请实施例提供的应用程序的资源更新方法,例如,如图3示出的应用程序的资源更新方法。
在一些实施例中,计算机可读存储介质可以是FRAM、ROM、PROM、EPROM、EEPROM、闪存、磁表面存储器、光盘、或CD-ROM等存储器;也可以是包括上述存储器之一或任意组合的各种设备。
在一些实施例中,可执行指令可以采用程序、软件、软件模块、脚本或代码的形式,按任意形式的编程语言(包括编译或解释语言,或者声明性或过程性语言)来编写,并且其可按任意形式部署,包括被部署为独立的程序或者被部署为模块、组件、子例程或者适合在计算环境中使用的其它单元。
作为示例,可执行指令可以但不一定对应于文件***中的文件,可以可被存储在保存其它程序或数据的文件的一部分,例如,存储在超文本标记语言(HTML,Hyper TextMarkup Language)文档中的一个或多个脚本中,存储在专用于所讨论的程序的单个文件中,或者,存储在多个协同文件(例如,存储一个或多个模块、子程序或代码部分的文件)中。
作为示例,可执行指令可被部署为在一个计算设备上执行,或者在位于一个地点的多个计算设备上执行,又或者,在分布在多个地点且通过通信网络互连的多个计算设备上执行。
综上所述,通过本申请实施例实现了动态替换资源,从而做到了进程无需重启就能实现资源的热部署生效。
以上所述,仅为本申请的实施例而已,并非用于限定本申请的保护范围。凡在本申请的精神和范围之内所作的任何修改、等同替换和改进等,均包含在本申请的保护范围之内。

Claims (15)

1.一种应用程序的资源更新方法,其特征在于,所述方法包括:
在应用程序运行过程中,获取所述应用程序的更新资源包,所述更新资源包中包括更新资源及可执行文件;
基于所述可执行文件,创建所述更新资源包对应的插件类加载器,并生成包括至少一个非插件类加载器的类加载器集合;
在所述应用程序对应的类加载器链中,获取宿主类加载器,并将所述宿主类加载器的父类加载器替换为所述插件类加载器,得到目标类加载器链;
基于所述类加载器集合、所述目标类加载器链中至少之一,确定用于加载所述更新资源归属的目标类的目标类加载器;
通过所述目标类加载器加载所述目标类,并基于所述更新资源,运行所述目标类对应的功能。
2.如权利要求1所述的方法,其特征在于,所述基于所述类加载器集合、所述目标类加载器链中至少之一,确定用于加载所述更新资源归属的目标类的目标类加载器,包括:
基于所述目标类加载器链中各节点对应的类加载器,确定用于加载所述更新资源归属的目标类的目标类加载器;
当基于所述目标类加载器链未能确定所述目标类加载器时,基于所述类加载器集合中的各类加载器,确定所述目标类加载器;
其中,所述目标类加载器链中的类加载器具有层级关系,所述类加载器集合中的类加载器不具有层级关系。
3.如权利要求2所述的方法,其特征在于,所述基于所述目标类加载器链中各节点对应的类加载器,确定用于加载所述更新资源归属的目标类的目标类加载器,包括:
基于所述目标类加载器链中各类加载器之间的层级关系,确定以所述插件类加载器为最低层级的子层级关系;
从所述插件类加载器开始,获取所述子层级关系中各层级的类加载器的类加载路径;
获取所述目标类的目标类加载路径,并将所述目标类加载路径与各所述类加载路径进行比对,得到比对结果;
当所述比对结果表征所述目标类加载路径与任一所述类加载路径不同时,将所述插件类加载器作为所述目标类的目标类加载器。
4.如权利要求2所述的方法,其特征在于,所述基于所述类加载器集合中的各类加载器,确定所述目标类加载器,包括:
获取所述类加载器集合中各类加载器的类加载路径;
获取所述目标类的目标类加载路径,并在所述各类加载器的类加载路径中查找所述目标类加载路径,得到查找结果;
当所述查找结果表征所述各类加载器的类加载路径中存在所述目标类加载路径时,将所述类加载路径所归属的类加载器,作为所述目标类加载器。
5.如权利要求1所述的方法,其特征在于,所述方法还包括:
识别所述更新资源归属的目标类的类型,所述类型包括宿主类、插件类;
其中,所述宿主类为,在安装所述应用程序时,通过宿主类加载器所加载的类,所述插件类为,在运行所述应用程序时,通过插件类加载器所加载的类;
所述基于所述类加载器集合、所述目标类加载器链中至少之一,确定用于加载所述更新资源归属的目标类的目标类加载器,包括:
当所述类型为宿主类时,从所述类加载器集合中的至少一个非插件类加载器中,确定用于加载所述目标类的目标类加载器;
当所述类型为插件类时,获取所述插件类加载器对应的引用类标识集合,并基于所述类加载器集合和所述目标类加载器链中之一、及所述引用类标识集合,确定用于加载所述目标类的目标类加载器;
其中,所述引用类标识为,所述插件类加载器中所引用的其他类的类标识。
6.如权利要求5所述的方法,其特征在于,所述基于所述类加载器集合和所述目标类加载器链中之一、及所述引用类标识集合,确定用于加载所述目标类的目标类加载器,包括:
将所述目标类的类标识与所述引用类标识集合中的各类标识进行匹配,得到匹配结果;
当所述匹配结果表征所述目标类的类标识属于所述引用类标识集合时,基于所述类加载器集合,确定用于加载所述目标类的目标类加载器;
当所述匹配结果表征所述目标类的类标识不属于所述引用类标识集合时,基于所述目标类加载器链,确定用于加载所述目标类的目标类加载器。
7.如权利要求1所述的方法,其特征在于,所述基于所述更新资源,运行所述目标类对应的功能之前,所述方法还包括:
获取所述更新资源的资源加载路径,及所述应用程序的资源加载器;
在所述资源加载器中所述应用程序的原始资源加载路径之前,***所述资源加载路径,得到目标资源加载路径;
根据所述目标资源加载路径所指示的加载顺序,将所述更新资源加载至所述应用程序的内存空间。
8.如权利要求7所述的方法,其特征在于,所述通过所述目标类加载器加载所述目标类,包括:
当基于所述类加载器集合、所述目标类加载器链中至少之一,能够确定所述目标类的目标类加载器时,获取所述目标类的类加载路径,并控制所述目标类加载器,基于所述类加载路径执行针对所述目标类的加载操作;
所述基于所述更新资源,运行所述目标类对应的功能,包括:
在执行所述加载操作的过程中,基于所述更新资源的资源标识,从所述应用程序的内存空间中,获取所述更新资源,并当所述加载操作完成时,基于所述更新资源,运行资源更新后的所述目标类对应的功能。
9.如权利要求1所述的方法,其特征在于,所述方法还包括:
当基于所述类加载器集合、所述目标类加载器链中至少之一,不能确定所述目标类的目标类加载器时,控制所述插件类加载器捕获异常信息,并基于所述异常信息,生成错误提示信息;
当运行所述目标类对应的功能时,展示所述错误提示信息;
其中,所述错误提示信息,用于表征基于所述更新资源包针对所述应用程序的更新操作失败。
10.如权利要求1所述的方法,其特征在于,所述在应用程序运行过程中,获取所述应用程序的更新资源包,包括:
在应用程序运行过程中,接收到服务器下发的更新通知,所述更新通知用于指示所述应用程序存在更新资源包;
依据所述更新通知,下载所述更新资源包至本地存储空间,并通知所述应用程序的进程,以使所述进程从所述本地存储空间中,获取所述更新资源包。
11.如权利要求1所述的方法,其特征在于,所述基于所述可执行文件,创建所述更新资源包对应的插件类加载器,包括:
解析所述可执行文件,得到所述更新资源包所包括的至少一个待加载类;
创建用于加载所述至少一个待加载类的插件类加载器;
所述生成包括至少一个非插件类加载器的类加载器集合,包括:
获取所述应用程序对应的至少一个非插件类加载器,并生成包括至少一个非插件类加载器、及除所述插件类加载器之外的其他插件类加载器的类加载器集合。
12.一种应用程序的资源更新装置,其特征在于,所述装置包括:
获取模块,用于在应用程序运行过程中,获取所述应用程序的更新资源包,所述更新资源包中包括更新资源及可执行文件;
生成模块,用于基于所述可执行文件,创建所述更新资源包对应的插件类加载器,并生成包括至少一个非插件类加载器的类加载器集合;
替换模块,用于在所述应用程序对应的类加载器链中,获取宿主类加载器,并将所述宿主类加载器的父类加载器替换为所述插件类加载器,得到目标类加载器链;
查找模块,用于基于所述类加载器集合、所述目标类加载器链中至少之一,确定用于加载所述更新资源归属的目标类的目标类加载器;
运行模块,用于通过所述目标类加载器加载所述目标类,并基于所述更新资源,运行所述目标类对应的功能。
13.一种电子设备,其特征在于,所述电子设备包括:
存储器,用于存储可执行指令;
处理器,用于执行所述存储器中存储的可执行指令时,实现权利要求1至11任一项所述的应用程序的资源更新方法。
14.一种计算机可读存储介质,存储有可执行指令,其特征在于,所述可执行指令被处理器执行时实现权利要求1至11任一项所述的应用程序的资源更新方法。
15.一种计算机程序产品,包括计算机程序或指令,其特征在于,所述计算机程序或指令被处理器执行时实现权利要求1至11任一项所述的应用程序的资源更新方法。
CN202210788001.1A 2022-07-04 2022-07-04 应用程序的资源更新方法、装置、设备及可读存储介质 Pending CN115129348A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202210788001.1A CN115129348A (zh) 2022-07-04 2022-07-04 应用程序的资源更新方法、装置、设备及可读存储介质

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202210788001.1A CN115129348A (zh) 2022-07-04 2022-07-04 应用程序的资源更新方法、装置、设备及可读存储介质

Publications (1)

Publication Number Publication Date
CN115129348A true CN115129348A (zh) 2022-09-30

Family

ID=83381802

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202210788001.1A Pending CN115129348A (zh) 2022-07-04 2022-07-04 应用程序的资源更新方法、装置、设备及可读存储介质

Country Status (1)

Country Link
CN (1) CN115129348A (zh)

Cited By (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN116610387A (zh) * 2023-07-17 2023-08-18 杭州比智科技有限公司 一种基于动态加载和bitmap实现渠道对接及数据分析方法

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN116610387A (zh) * 2023-07-17 2023-08-18 杭州比智科技有限公司 一种基于动态加载和bitmap实现渠道对接及数据分析方法
CN116610387B (zh) * 2023-07-17 2023-10-03 杭州比智科技有限公司 一种基于动态加载和bitmap实现渠道对接及数据分析方法

Similar Documents

Publication Publication Date Title
US10949191B2 (en) Patch-upgrade-based file processing method and apparatus, terminal, and storage medium
CN105657191B (zh) 一种基于Android***的应用增量升级方法及***
CN110874236B (zh) 一种跨平台应用装置、终端及存储介质
CN111090452B (zh) 服务环境的切换方法及计算机可读存储介质
CN114077423A (zh) 基于移动跨平台的机场app开发容器架构
CN106569880B (zh) 一种Android应用间动态共享资源的方法及***
CN101694625A (zh) 基于加密服务器管理的客户端软件更新方法及装置
CN108089873A (zh) 一种应用组件即时更新的方法及终端
CN112769706B (zh) 组件化路由方法及***
CN112114890A (zh) 小程序的处理方法、装置、设备及存储介质
CN115237631A (zh) 一种基于数据共享插件的易扩展式数据共享***及方法
CN115129348A (zh) 应用程序的资源更新方法、装置、设备及可读存储介质
CN113010178B (zh) 应用程序运行控制方法、装置、设备和介质
CN108228266B (zh) 一种Android插件框架下不同插件间启动Fragment组件的方法和装置
CN111090442B (zh) 一种应用更新方法、装置和存储介质
CN113031957A (zh) 应用程序的安装方法、客户端、终端、服务器及存储介质
CN116755788A (zh) 一种线上规则修改方法、装置、设备及存储介质
CN115729590A (zh) 服务部署方法、装置、设备和计算机可读存储介质
CN115859280A (zh) 内存马的检测方法、装置、设备及存储介质
CN113590179B (zh) 插件检测方法、装置、电子设备及存储介质
CN115374083A (zh) 数据源的切换方法、装置、电子设备及存储介质
CN112667491B (zh) 虚拟机的功能测试方法及装置
CN114579167A (zh) 一种下载应用升级文件的方法、装置及存储介质
US11017032B1 (en) Document recovery utilizing serialized data
CN112379973A (zh) 重载方法和装置

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination