掌桥专利:专业的专利平台
掌桥专利
首页

一种动态更新软件开发工具包的方法、设备及存储介质

文献发布时间:2023-06-19 12:24:27


一种动态更新软件开发工具包的方法、设备及存储介质

技术领域

本申请实施例涉及金融科技(Fintech)的数据处理技术领域,涉及但不限于一种动态更新软件开发工具包的方法、设备及计算机可读存储介质。

背景技术

随着计算机技术的发展,越来越多的技术应用在金融领域,传统金融业正在逐步向金融科技(Fintech)转变,然而,由于金融行业的安全性、实时性要求,金融科技也对技术提出了更高的要求。

金融科技领域下,在移动终端上可以通过各种应用程序直接地向用户展示各种信息,目前通过应用程序向用户展示信息较为常用的方式是将软件开发工具包(SoftwareDevelopmentKit,SDK)作为一个整体嵌入到应用中。SDK的更新需要通过组件链接器进行,而且每次更新需要生成补丁,补丁合成的时候,有可能补丁合成失败,那回退到老的版本会增加成本。现有的SDK更新方式是通过解压,重新封装,复制dex文件或者so文件实现更新SDK。

然而,这种更新方式不仅繁琐,而且对文件进行操作的过程中容易出现异常,比如程序突然退出或者设备断电都会导致写文件失败,因此,复制dex文件或者so文件来更新SDK这种方式极易出现问题,导致更新失败。

发明内容

本申请实施例提供一种动态更新软件开发工具包的方法、设备及计算机可读存储介质,以解决相关技术中通过复制dex文件或者so文件,来更新SDK这种方式极易出现更新失败的问题。

本申请实施例的技术方案是这样实现的:

本申请实施例提供一种动态更新软件开发工具包的方法,包括:

当宿主应用程序启动时,确定工具开发端所述宿主应用程序对应的软件开发工具包包括的目标插件发生更新;

将更新后的所述目标插件拷贝到所述宿主应用程序的工程目录下;

通过钩子改变类的加载机制,基于改变后的加载机制在所述宿主应用程序中加载所述目标插件的类,反射调用所述目标插件的类的方法,以实现所述目标插件。

本申请实施例提供一种设备,包括:

存储器,用于存储可执行指令;处理器,用于执行存储器中存储的可执行指令时,实现上述的方法。

本申请实施例提供一种计算机可读存储介质,存储有可执行指令,用于引起处理器执行时,实现上述的方法。

本申请实施例具有以下有益效果:

通过当宿主应用程序启动时,确定工具开发端宿主应用程序对应的软件开发工具包包括的目标插件发生更新;将更新后的目标插件拷贝到宿主应用程序的工程目录下;通过钩子改变类的加载机制,基于改变后的加载机制在宿主应用程序中加载目标插件的类,反射调用目标插件的类的方法,以实现目标插件;如此,摒弃了对插件的dex文件进行封装和复制来更新SDK的方式,实现了插件化更新SDK,不仅减少了文件操作失败的概率,而且,本申请还可以将SDK拆分成很多个插件,从而确保能够尽可能细粒度的更新插件,即在某一插件发生更新的情况下,采用插件化更新方式实现对SDK的更新,如此,节省了下载插件的流量和集成插件的时间。

附图说明

图1是本申请实施例提供的一种多线程并发场景的示意图;

图2是本申请实施例提供的动态更新软件开发工具包的方法的一个可选的流程示意图;

图3是本申请实施例提供的动态更新软件开发工具包的方法的一个可选的流程示意图;

图4是本申请实施例提供的门禁刷脸SDK的一个可选的架构示意图;

图5是本申请实施例提供的动态更新软件开发工具包的方法对应的插件更新场景示意图;

图6是本申请实施例提供的动态更新软件开发工具包的方法的一个可选的流程示意图;

图7是本申请实施例提供的类加载器加载新的宿主dexElements的示意图;

图8是本申请实施例提供的动态更新软件开发工具包的方法的一个可选的流程示意图;

图9是本申请实施例提供的动态更新软件开发工具包的方法的一个可选的流程示意图。

具体实施方式

为了使本申请的目的、技术方案和优点更加清楚,下面将结合附图对本申请作进一步地详细描述,所描述的实施例不应视为对本申请的限制,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其它实施例,都属于本申请保护的范围。

在以下的描述中,涉及到“一些实施例”,其描述了所有可能实施例的子集,但是可以理解,“一些实施例”可以是所有可能实施例的相同子集或不同子集,并且可以在不冲突的情况下相互结合。除非另有定义,本申请实施例所使用的所有的技术和科学术语与属于本申请实施例的技术领域的技术人员通常理解的含义相同。本申请实施例所使用的术语只是为了描述本申请实施例的目的,不是旨在限制本申请。

下面说明本申请实施例提供的动态更新软件开发工具包的设备的示例性应用,本申请实施例提供的动态更新软件开发工具包的设备可以实施为笔记本电脑,平板电脑,台式计算机,移动设备(例如,移动电话,便携式音乐播放器,个人数字助理,专用消息设备,便携式游戏设备),智能机器人等任意具有屏幕显示功能的终端,也可以实施为服务器。下面,将说明动态更新软件开发工具包的设备实施为终端时的示例性应用。

参见图1,图1是本申请实施例提供的终端100的结构示意图,图1所示的终端100包括:至少一个处理器110、至少一个网络接口120、用户接口130和存储器150。终端100中的各个组件通过总线系统140耦合在一起。可理解,总线系统140用于实现这些组件之间的连接通信。总线系统140除包括数据总线之外,还包括电源总线、控制总线和状态信号总线。但是为了清楚说明起见,在图1中将各种总线都标为总线系统140。

处理器110可以是一种集成电路芯片,具有信号的处理能力,例如通用处理器、数字信号处理器(DSP,Digital Signal Processor),或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等,其中,通用处理器可以是微处理器或者任何常规的处理器等。

用户接口130包括使得能够呈现媒体内容的一个或多个输出装置131,包括一个或多个扬声器和/或一个或多个视觉显示屏。用户接口130还包括一个或多个输入装置132,包括有助于用户输入的用户接口部件,比如键盘、鼠标、麦克风、触屏显示屏、摄像头、其他输入按钮和控件。

存储器150可以是可移除的,不可移除的或其组合。示例性地硬件设备包括固态存储器,硬盘驱动器,光盘驱动器等。存储器150可选地包括在物理位置上远离处理器110的一个或多个存储设备。存储器150包括易失性存储器或非易失性存储器,也可包括易失性和非易失性存储器两者。非易失性存储器可以是只读存储器(Read Only Memory,ROM),易失性存储器可以是随机存取存储器(Random Access Memory,RAM)。本申请实施例描述的存储器150旨在包括任意适合类型的存储器。在一些实施例中,存储器150能够存储数据以支持各种操作,这些数据的示例包括程序、模块和数据结构或者其子集或超集,下面示例性说明。

操作系统151,包括用于处理各种基本系统服务和执行硬件相关任务的系统程序,例如框架层、核心库层、驱动层等,用于实现各种基础业务以及处理基于硬件的任务;

网络通信模块152,用于经由一个或多个(有线或无线)网络接口120到达其他计算设备,示例性地网络接口120包括:蓝牙、无线相容性认证(WiFi)、和通用串行总线(Universal Serial Bus,USB)等;

输入处理模块153,用于对一个或多个来自一个或多个输入装置132之一的一个或多个用户输入或互动进行检测以及翻译所检测的输入或互动。

在一些实施例中,本申请实施例提供的装置可以采用软件方式实现,图1示出了存储在存储器150中的一种动态更新软件开发工具包的装置154,该动态更新软件开发工具包的装置154可以是终端100中的动态更新软件开发工具包的装置,其可以是程序和插件等形式的软件,包括以下软件模块:处理模块1541、获取模块1542,这些模块是逻辑上的,因此根据所实现的功能可以进行任意的组合或进一步拆分。将在下文中说明各个模块的功能。

在另一些实施例中,本申请实施例提供的装置可以采用硬件方式实现,作为示例,本申请实施例提供的装置可以是采用硬件译码处理器形式的处理器,其被编程以执行本申请实施例提供的动态更新软件开发工具包的方法,例如,硬件译码处理器形式的处理器可以采用一个或多个应用专用集成电路(Application Specific Integrated Circuit,ASIC)、DSP、可编程逻辑器件(Programmable Logic Device,PLD)、复杂可编程逻辑器件(Complex Programmable Logic Device,CPLD)、现场可编程门阵列(Field-ProgrammableGate Array,FPGA)或其他电子元件。

下面将结合本申请实施例提供的终端100的示例性应用和实施,说明本申请实施例提供的动态更新软件开发工具包的方法。参见图2,图2是本申请实施例提供的动态更新软件开发工具包的方法的一个可选的流程示意图,将结合图2示出的步骤进行说明,

步骤S201,当宿主应用程序启动时,确定工具开发端宿主应用程序对应的软件开发工具包包括的目标插件发生更新。

本申请提供的动态更新软件开发工具包的方法,基于组件化架构思想进行最细粒度的拆分模块,把所有组件模块做成插件,实现插件化更新软件开发工具包SDK。这里,对组件化和插件化进行解释说明,组件化指将一个应用程序(Application,APP)分成多个代码模块,每个代码模块就是一个组件(Module),开发的过程中可以让这些组件相互依赖或者单独调试部分组件等,但是最终发布的时候是将这些组件合并成一个安卓应用程序包(Android application package,APK)。插件化是指将整个APP拆分成多个功能模块,这些功能模块包括一个宿主和多个插件,每个功能模块都是一个APK,最终打包的时候将宿主APK和插件APK分开或者联合打包。

本申请实施例中,步骤S201当宿主应用程序启动时,确定工具开发端宿主应用程序对应的软件开发工具包包括的目标插件发生更新,可以通过如下步骤实现:

首先,当宿主应用程序启动时,获取本地与云端同一插件的版本号;

其次,当同一插件在本地对应的版本号与在云端对应的版本号之间存在目标关联关系,确定同一插件发生更新,其中,目标插件包括同一插件。

示例性的,终端确定同一插件在本地对应的版本号小于云端对应的版本号,则终端确定同一插件在本地对应的版本号与在云端对应的版本号之间存在目标关联关系,此时,确定该插件发生更新。

在实际应用中,SDK包括的每个插件都有名称和版本号。更新插件时,待更新的插件存在于云端,在宿主应用程序每次启动时检测插件版本号决定是否下载进行更新。如果有,则在下载成功后,终端将插件进行替换。

此外,为了提高灵活性,确定工具开发端宿主应用程序对应的软件开发工具包包括的目标插件发生更新,还可以通过如下步骤实现:

当宿主应用程序启动时,获取本地插件的最近一次更新时刻;

若最近一次更新时刻与当前时刻的时长大于预设时长,确定该插件为目标插件,并从云端中更细该目标插件。其中,当前时刻可以理解为宿主应用程序启动的时刻。

可以理解,通过上述方式,实现了插件更新时,除了根据版本号进行更新,还可根据本地更新时长进行更新,实现目标插件更新的灵活性。

步骤S202,将更新后的目标插件拷贝到宿主应用程序的工程目录下。

本申请实施例中,终端确定本地的某一插件在云端存在更新后的目标插件时,将更新后的目标插件拷贝到宿主应用程序的工程目录下,以便后续执行插件化更新SDK的步骤。

步骤S203,通过钩子改变类的加载机制,基于改变后的加载机制在宿主应用程序中加载目标插件的类,反射调用目标插件的类的方法,以实现目标插件。

这里,宿主应用程序是安装运行的APK,当android系统的JVM加载宿主应用程序的dex文件时,可以调用到宿主应用程序的类的方法,宿主应用程序要实现插件功能必须调用插件的方法,本申请通过改变后的加载机制在宿主应用程序中加载目标插件的类,反射调用目标插件的类的方法,便可以实现目标插件,至此,目标插件便可以执行这些类的方法了。

本申请实施例中,下载的更新后的目标插件即新插件,SDK采用反射方式进行hook(钩子)android系统底层代码。根据android系统Java虚拟机(Java Virtual Machine,JVM)的类加载的流程,在宿主应用程序里面获取到类加载器后,改变类加载的对象,将更新后的目标插件apk中的dex插入到宿主应用程序的可执行文件数组dexElements中去运行更新后的目标插件apk,从而实现在宿主应用程序可以调用更新后的目标插件的方法。

这里,对改变类加载的对象的实现过程进行进一步地说明,本申请实施例中通过hook改变类的加载机制时,可以通过调用了BaseDexClassLoader.find Class()来实现,而在findClass()方法里面,是通过循环遍历Element[]去调用每个Element数组元素的findClass(),Element数组元素就是dex文件。宿主程序一启动,JVM会自动加载宿主的dex文件,此时宿主的的dexElements里面就是宿主所有的dex文件,可以直接调用宿主的类及其方法。但是插件的类dex文件不在宿主的dexElements里面,所以不能直接调用插件的类。由于dexElements是数组,本申请提出通过反射方式进行hook宿主的类加载,具体地,获取宿主的dexElements和插件的dexElements,合并生成一个新的dexElements,让宿主去加载这个新的dexElements,那这样就把插件和宿主的dex加载到宿主里面了,实现了类加载的对象的改变。

目前更新SDK时,采用的是SDK的差分升级方式,需要通过在云端发布平台进行的插件差分处理和在工具应用终端进行插件还原处理,同时需要依赖组件链接器进行插件的动态更新。另外插件补丁是通过解压,重新封装,复制文件达到补丁更新的,更新机制繁杂;复制dex文件或者so文件来更新SDK极易出现问题,导致更新失败。然而,申请区正是摒弃了对插件的dex文件进行封装和复制来更新SDK的方式,实现了插件化更新SDK,不仅减少了文件操作失败的概率,而且,能够尽可能细粒度的更新插件,如此,节省了下载插件的流量和集成插件的时间。

本申请提供的动态更新软件开发工具包的方法,通过当宿主应用程序启动时,确定工具开发端宿主应用程序对应的软件开发工具包包括的目标插件发生更新;将更新后的目标插件拷贝到宿主应用程序的工程目录下;通过钩子改变类的加载机制,基于改变后的加载机制在宿主应用程序中加载目标插件的类,反射调用目标插件的类的方法,以实现目标插件;如此,摒弃了对插件的dex文件进行封装和复制来更新SDK的方式,实现了插件化更新SDK,不仅减少了文件操作失败的概率,而且,能够尽可能细粒度的更新插件,如此,节省了下载插件的流量和集成插件的时间,减少了维护成本。

当然,本申请其他实施例中,还可以把整个SDK就划分成一个插件或少量的插件。这种划分方式能够实现插件化更新SDK,但是相比于细粒度的拆分模块并把所有组件模块做成插件方式,更新速度边长,消耗流程也会增多。

在一些实施例中,步骤S201当宿主应用程序启动时,确定工具开发端宿主应用程序对应的软件开发工具包包括的目标插件发生更新之前,可以通过图3所示的步骤得到宿主应用程序:

步骤S301,获取工具开发端发布的软件开发工具包。

其中,软件开发工具包包括二进制归档文件和至少两个插件,至少两个插件包括目标插件。这里,二进制归档文件包括aar文件,aar文件提供给终端调用至少两个插件的接口。

步骤S302,将二进制归档文件和至少两个插件拷贝到应用程序的工程目录下。

步骤S303,通过应用程序调用二进制归档文件中的接口,集成至少两个插件,得到宿主应用程序。

这里,终端将二进制归档文件和至少两个插件拷贝到应用程序的工程目录下,终端通过应用程序调用aar文件中的接口,集成至少两个插件,得到宿主应用程序,宿主应用程序是安装运行的APK,android系统的JVM加载宿主应用程序的dex文件,如此可以调用到宿主应用程序的类的方法,宿主应用程序要实现插件功能必须调用插件的方法。

示例性的,参见图4所示,以更新门禁刷脸SDK为例,门禁刷脸SDK的架构如图4所示,门禁刷脸SDK401由一个aar文件402和多个插件403组成,这里采用插件化更新SDK将不同功能做成插件。示例性的,门禁刷脸SDK包括初始化插件、人脸识别插件、明细上报插件、任务下发插件、网络请求插件、android本地数据库如微信数据库(WeChat Database,WCDB)数据库插件、人工智能(Artificial Intelligence,AI)算法人脸检测插件、AI算法红外活体插件、AI算法翻拍活体插件、AI算法人脸检索插件、标准(normal)公共库插件、数据分析上报插件、日志库插件、相机库插件。终端在加载插件的时候需用到dex文件和so文件,而插件就是APK,里面包含dex文件和so文件和资源文件。终端下载新的插件所需流量和加载插件包大小,决定了将功能做成多个插件。出现了bug或者某个插件升级时,终端从云端找到对应的插件更新即可,其他插件则不用更新,如此,终端下载新的插件就可以大大减少流量消耗。多个插件的划分采用组件化架构方案,从而尽可能小粒度划分各个模块成为单独的插件。这里,aar就是一个调用SDK方法以启动SDK的壳子,用于终端更好的接入云端SDK。

本申请提供了插件化更新门禁刷脸SDK的方式,提供了一个aar文件和多个插件。由于门禁刷脸SDK包含多个模块,尤其是多套算法模型文件很大,这就导致门禁刷脸SDK如果按照复制dex文件或者so文件来更新SDK时耗费大量的流量,特别是很多门禁设备是物联网卡的话,那对流量更是要求高。为此,本申请提供组件化架构思想,将模块拆分成很多插件以尽可能细粒度的更新门禁刷脸SDK,从而节省下载插件的流量和加载插件时间。当门禁刷脸SDK需要升级时,门禁刷脸SDK端的插件下发到设备端动态更新。终端集成的时候,将aar和所有插件拷贝到工程目录下,调用SDK的aar里面提供的接口就可以实现门禁刷脸。插件化更新门禁刷脸SDK实现的原理是,根据android JM类加载的原理和阅读系统底层源码,宿主应用程序将更新后的插件的dex文件加载进来,那宿主应用程序就能调用更新后的插件的类及其方法。

在一些实施例中,步骤S202将更新后的目标插件拷贝到宿主应用程序的工程目录下,可以通过如下步骤实现:将更新后的目标插件包含的虚拟机的可执行文件和动态库文件加载到工程目录下。其中,虚拟机的可执行文件包括dex文件,动态库文件包括so文件。

示例性的,参见图5所示,在一个可实现的插件更新场景中,工具开发端501又称为SDK端,更新插件,并且将更新后的插件推送到云端502,用户终端503从云端获取更新后的插件并在终端侧实现该插件。

这里,每个插件的名称用以标志不同的插件,每个插件内部有一个版本号,存在APK内部的一个文本文档(TXT)里。当SDK端对插件有更新时,新的插件推动至云端。用户终端的应用每次启动的时候,会请求云端查看是否有新的插件。比较方法是:在终端找到与云端插件名称相同的插件,找到了比较两者版本号是否相同,以决定是否下载云端插件;若没有找到名称相同的插件,不用更新。下载的新插件可以统一放置在原来老插件的位置进行替换即可,插件可以选择选择安全数码卡(Secure Digital Memory Card,SD)或者内置存储,这里,门禁刷脸SDK选择应用程序内部,防止用户不小心删除了SD卡的内容。如果下载失败,那么插件自然保留老插件不受影响,插件版本号也还是老的插件版本号。

插件就是APK,也就是压缩包,APK包含dex、libs、res。其中,dex存放编译好的类的二进制字节码文件、前端资源(assets)文件存放算法模型库、libs存放so库、res存放资源文件。由于门禁刷脸SDK没有界面等资源文件,所以res目录为空。用户终端集成门禁刷脸SDK后的APK,我们称为宿主。宿主才是安装运行的APK,android系统的JVM加载宿主的dex文件,以调用到宿主的类的方法。宿主要实现门禁刷脸功能必须调用SDK中插件的方法。插件也是APK,作为SDK的一部分拷贝到工程里面,是未安装的APK,所以宿主是无法调用插件的类的方法。本申请通过hook改变类的加载机制实现在宿主内加载插件的类。类加载进来了,再通过反射调用类的方法和获取类的属性了。在类的加载阶段,JVM完成三件事:第一、通过一个类的全限定名来获取定义此类的二进制字节流。第二、将这个字节流所代表的静态存储结构转化为方法区域的运行时数据结构。第三、在java堆中生成一个代表这个类的Class对象,作为方法区域数据的访问入口。也就是说JVM通过类加载器ClasssLoader把dex里面的每个类加载进去后,就能执行这些类的方法。

进一步地,虚拟机的可执行文件包括dex文件,上述将更新后的目标插件包含的虚拟机的可执行文件加载到工程目录下,可以通过图6所示的步骤实现:

步骤S601,通过反射方式获取宿主应用程序的dexElements和目标插件的dexElements。

这里,终端通过反射方式进行hook系统底层源码。获取宿主应用程序类加载器后,反射方式得到宿主应用程序的dexElements数组对象;创建目标插件的类加载器,反射方式得到目标插件的dexElements对象。

步骤S602,合并宿主应用程序的dexElements和目标插件的dexElements,得到目标dexElements。

步骤S603,将目标dexElements赋值给宿主应用程序的dexElements。

这里,终端将宿主应用程序的dexElements和目标插件的dexElements这两者合并成目标dexElements即新的dexElements数组,然后再通过反射将这个新的dexElements数组对象通过反射赋值给宿主的dexElements。也就是说,结合图7所示,此时宿主应用程序的dexElements即新的宿主dexElements701变成了宿主应用程序的dexElement和目标插件的dexElements。这样宿主应用程序一启动可以加载目标插件的dex的所有类及其方法了。

进一步地,对类的加载进行进一步地说明,一个java程序来是由多个class类组成的,在运行程序的过程中需要通过ClassLoader将class类载入到JVM中才可以正常运行。而Android程序需要正常运行,也同样需要有ClassLoader机制将class类加载到Android的Dalvik/ART中,只不过它和java中的ClassLoader不一样在于Android的APK打包,是将class文件打包成一个或者多个dex文件,再由BaseDexClassLoader来进行处理。通过查看源码,本申请确定类的加载是可以通过DexClassLoader把一个dex文件进行加载,从而把dex对应的所有类成功加载。类的加载最终是调用BaseDexClassLoader的findClass()实现类的加载。整个加载过程是:首先检测这个类是否被加载了,如果已经加载,直接获取并返回。如果没有加载,parent不为null,则调用parent.loadClass进行加载,依次递归,如果找到了或者加载了就返回,没有找到也加载不了,才自己去加载。

进一步地,动态库文件包括so文件,上述将更新后的目标插件包含的动态库文件加载到工程目录下,可以通过图8所示的步骤实现:

步骤S801,合并宿主应用程序的nativeLibraryPathElements和目标插件的nativeLibraryPathElements,得到目标nativeLibraryPathElements。

其中,nativeLibraryPathElements数组指的是动态库路径数组。

步骤S802,将目标nativeLibraryPathElements赋值给宿主应用程序的nativeLibraryPathElements。

本申请实施例中,由于dex是普通类的二进制字节码文件,如果要调用插件so包的方法,同样可以通过反射的方式进行hook,设置宿主的nativeLibraryPathElements为宿主的nativeLibraryPathElements加上插件的nativeLibraryPathElements,进行合并后的数组赋值给宿主的nativeLibraryPathElements。以上是普通类的调用。针对libs目录下面的so文件,我们也需要能够调用到插件的so的方法。如果仅仅是使用添加Dex路径(addDexPath)方法将插件dex插入到宿主dexElements中,那么插件APK中存在加载so的话,是会抛出UnsatisfiedLinkError异常,因为dex里面没有so文件。通过System.loadLibrary源码是通过BaseDexClassLoader中的nativeLibraryPathElements数组来遍历查询子element来获得librarypath,本申请定位到nativeLibraryPathElements,nativeLibraryPathElements数组是通过makePathElements方法构建生成的,所以本申请通过反射去调用makePathElements方法,将librarySearchPath路径传入,从而获得新的nativeLibraryPathElements数组,然后将新旧合并。Hook的方式与上面的普通类的方式相同。

针对插件中assets目录下的算法模型文件,由于SDK只是去加载对应目录下的文件可以,所以下载插件后,将插件APK解压,把assets目录下的算法模型文件拷贝到宿主APK对应的data assets目录下,进行替换安装即可。

本申请其他实施例中,软件开发工具包还包括至少两个算法插件,宿主应用程序可以在不同的算法之间进行切换,本申请提供的动态更新软件开发工具包的方法,还包括如图9所示的步骤:

步骤S901,当宿主应用程序检测到算法切换事件,获取云端下发的至少两个算法类型标志位。

步骤S902,通过中间层从至少两个算法类型标志位中,选择与算法切换事件对应的目标算法标志位,并基于目标算法标志位从云端加载目标算法插件。

本申请实施例中,终端通过中间层实现在多套算法之间的自由加载和切换,当宿主应用程序检测到算法切换事件,终端基于算法切换事件下发请求以加载切换后的算法,即加载切换后的算法插件,然后调用中间层的算法应用程序接口(ApplicationProgramming Interface,API)即可。需要说明的是,当需要切换算法时,只需要根据云端下发的算法类型标志位在终端的中间层改变算法类型标志位即可。调用到中间层方法是,中间层根据内部算法标志位去加载云端的特定插件即可。这样可以大大减少包的体积,而且维护成本也很低。

步骤S903,将目标算法插件解压,并将解压后的算法模型文件拷贝到宿主应用程序对应的数据原生资源文件目录下,以替换数据原生资源文件目录下的算法模型文件,并安装解压后的算法模型文件。

下面继续说明本申请实施例提供的动态更新软件开发工具包的装置154实施为软件模块的示例性结构,在一些实施例中,如图1所示,存储在存储器150的动态更新软件开发工具包的装置154中的软件模块可以是终端100中的动态更新软件开发工具包的装置,包括:

处理模块1541,用于当宿主应用程序启动时,确定工具开发端宿主应用程序对应的软件开发工具包包括的目标插件发生更新。

处理模块1541,用于将更新后的目标插件拷贝到宿主应用程序的工程目录下。

处理模块1541,用于通过钩子改变类的加载机制,基于改变后的加载机制在宿主应用程序中加载目标插件的类,反射调用目标插件的类的方法,以实现目标插件。

在一些实施例中,动态更新软件开发工具包的装置154还包括获取模块1542,用于获取工具开发端发布的软件开发工具包,其中,软件开发工具包包括二进制归档文件和至少两个插件,至少两个插件包括目标插件。

处理模块1541,还用于将二进制归档文件和至少两个插件拷贝到应用程序的工程目录下;通过应用程序调用二进制归档文件中的接口,集成至少两个插件,得到宿主应用程序。

在一些实施例中,处理模块1541,还用于将更新后的目标插件包含的虚拟机的可执行文件和动态库文件加载到工程目录下。

在一些实施例中,虚拟机的可执行文件包括dex文件,处理模块1541,还用于通过反射方式获取宿主应用程序的dexElements和目标插件的dexElements;合并宿主应用程序的dexElements和目标插件的dexElements,得到目标dexElements;将目标dexElements赋值给宿主应用程序的dexElements。

在一些实施例中,动态库文件包括so文件,处理模块1541,还用于合并宿主应用程序的nativeLibraryPathElements和目标插件的nativeLibraryPathElements,得到目标nativeLibraryPathElements;将目标nativeLibraryPathElements赋值给宿主应用程序的nativeLibraryPathElements。

在一些实施例中,获取模块1542,还用于当宿主应用程序检测到算法切换事件,获取云端下发的至少两个算法类型标志位;

处理模块1541,还用于通过中间层从至少两个算法类型标志位中,选择与算法切换事件对应的目标算法标志位,并基于目标算法标志位从云端加载目标算法插件。

在一些实施例中,处理模块1541,还用于将目标算法插件解压,并将解压后的算法模型文件拷贝到宿主应用程序对应的数据原生资源文件目录下,以替换数据原生资源文件目录下的算法模型文件,并安装解压后的算法模型文件。

在一些实施例中,处理模块1541,还用于当宿主应用程序启动时,获取本地与云端同一插件的版本号;当同一插件在本地对应的版本号与在云端对应的版本号之间存在目标关联关系,确定同一插件发生更新,其中,目标插件包括同一插件。

需要说明的是,本申请实施例装置的描述,与上述方法实施例的描述是类似的,具有同方法实施例相似的有益效果,因此不做赘述。对于本装置实施例中未披露的技术细节,请参照本申请方法实施例的描述而理解。

本申请实施例提供一种存储有可执行指令的存储介质,其中存储有可执行指令,当可执行指令被处理器执行时,将引起处理器执行本申请实施例提供的方法,例如,如图2示出的方法。

在一些实施例中,存储介质可以是计算机可读存储介质,例如,铁电存储器(FRAM,Ferromagnetic Random Access Memory)、只读存储器(ROM,Read Only Memory)、可编程只读存储器(PROM,Programmable Read Only Memory)、可擦除可编程只读存储器(EPROM,Erasable Programmable Read Only Memory)、带电可擦可编程只读存储器(EEPROM,Electrically Erasable Programmable Read Only Memory)、闪存、磁表面存储器、光盘、或光盘只读存储器(CD-ROM,Compact Disk-Read Only Memory)等存储器;也可以是包括上述存储器之一或任意组合的各种设备。

在一些实施例中,可执行指令可以采用程序、软件、软件模块、脚本或代码的形式,按任意形式的编程语言(包括编译或解释语言,或者声明性或过程性语言)来编写,并且其可按任意形式部署,包括被部署为独立的程序或者被部署为模块、组件、子例程或者适合在计算环境中使用的其它单元。

作为示例,可执行指令可以但不一定对应于文件系统中的文件,可以可被存储在保存其它程序或数据的文件的一部分,例如,存储在超文本标记语言(超文本标记语言,Hyper Text Markup Language)文档中的一个或多个脚本中,存储在专用于所讨论的程序的单个文件中,或者,存储在多个协同文件(例如,存储一个或多个模块、子程序或代码部分的文件)中。作为示例,可执行指令可被部署为在一个计算设备上执行,或者在位于一个地点的多个计算设备上执行,又或者,在分布在多个地点且通过通信网络互连的多个计算设备上执行。

以上所述,仅为本申请的实施例而已,并非用于限定本申请的保护范围。凡在本申请的精神和范围之内所作的任何修改、等同替换和改进等,均包含在本申请的保护范围之内。

相关技术
  • 一种动态更新软件开发工具包的方法、设备及存储介质
  • 软件开发工具包的更新方法、装置、电子设备及存储介质
技术分类

06120113284312