CN115934123A - 一种客户端逻辑更新方法、装置、电子设备及存储介质 - Google Patents
一种客户端逻辑更新方法、装置、电子设备及存储介质 Download PDFInfo
- Publication number
- CN115934123A CN115934123A CN202211504405.XA CN202211504405A CN115934123A CN 115934123 A CN115934123 A CN 115934123A CN 202211504405 A CN202211504405 A CN 202211504405A CN 115934123 A CN115934123 A CN 115934123A
- Authority
- CN
- China
- Prior art keywords
- program
- plug
- client logic
- updated
- application
- 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
Links
Images
Classifications
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Landscapes
- Stored Programmes (AREA)
Abstract
本公开的实施方式提供了一种客户端逻辑更新方法、装置、电子设备及存储介质。该方法可以包括:响应于确定应用程序的客户端逻辑待更新,获取与待更新的客户端逻辑对应的插件程序的程序代码文件;其中,所述应用程序与所述插件程序之间的共享接口是基于Kotlin语言定义的;根据获取到的程序代码文件,将所述插件程序加载至所述应用程序;执行所述插件程序,以实现与所述插件程序对应的客户端逻辑。
Description
技术领域
本公开的实施方式涉及应用技术领域,更具体地,本公开的实施方式涉及一种客户端逻辑更新方法、装置、电子设备及存储介质。
背景技术
本部分旨在为权利要求书中陈述的本公开的实施方式提供背景或上下文。此处的描述不因为包括在本部分中就承认是现有技术。
原生开发(Native App开发),是指为特定平台开发应用程序时,可以利用该平台提供的开发框架、开发语言、开发类库进行开发。
在针对已发布的原生开发应用程序进行客户端逻辑更新的场景中,通常需要重新发布应用程序的新版本,以使用户可以通过应用市场或已安装的应用程序的旧版本客户端,下载并安装新版本客户端,来更新应用程序的客户端逻辑。
由此可见,受限于应用市场的上架流程、用户的更新行为等因素,原生开发应用程序的客户端逻辑难以及时进行更新。
发明内容
在本公开实施方式的第一方面中,提供了一种客户端逻辑更新方法,所述方法包括:
响应于确定应用程序的客户端逻辑待更新,获取与待更新的客户端逻辑对应的插件程序的程序代码文件;其中,所述应用程序与所述插件程序之间的共享接口是基于Kotlin语言定义的;
根据获取到的程序代码文件,将所述插件程序加载至所述应用程序;
执行所述插件程序,以实现与所述插件程序对应的客户端逻辑。
在本公开实施方式的第二方面中,提供了一种客户端逻辑更新装置,所述装置包括:
第一获取模块,用于响应于确定应用程序的客户端逻辑待更新,获取与待更新的客户端逻辑对应的插件程序的程序代码文件;其中,所述应用程序与所述插件程序之间的共享接口是基于Kotlin语言定义的;
加载模块,用于根据获取到的程序代码文件,将所述插件程序加载至所述应用程序;
执行模块,用于执行所述插件程序,以实现与所述插件程序对应的客户端逻辑。
在本公开实施方式的第三方面中,提供了一种电子设备,包括:
处理器;
用于存储所述处理器可执行指令的存储器;
其中,所述处理器被配置为执行所述客户端逻辑更新方法。
在本公开实施方式的第四方面中,提供了一种计算机可读存储介质,其上存储有计算机程序,该程序被处理器执行时实现所述客户端逻辑更新方法。
本公开以上的实施方式,至少具有如下的有益效果:
一方面,由于可以将需要更新的部分客户端逻辑,以插件程序的形式动态加载至原生开发的应用程序,并可以基于客户端内嵌的JS引擎执行动态下发的插件程序,从而在无需客户端重新发版的情况下,能够针对已发布的原生开发的应用程序及时地进行客户端逻辑更新,同时可以保证客户端逻辑更新后的执行高性能。
另一方面,由于原生开发的应用程序与动态下发的插件程序之间的共享接口是基于Kotlin语言定义的,可以被JVM、JS、Native三个平台共享,因此开发人员在编写插件程序的程序代码的过程中,无需通过文档统一约定各个接口分别在原生侧与JS侧的定义与使用方式,无需过多考虑桥接细节,也无需编写相应的转换代码,从而在针对已发布的原生开发应用程序进行客户端逻辑更新的场景中,能够同时保证客户端逻辑的更新及时性与开发高效性。
附图说明
通过参考附图阅读下文的详细描述,本公开示例性实施方式的上述以及其他目的、特征和优点将变得易于理解。在附图中,以示例性而非限制性的方式示出了本公开的若干实施方式,其中:
图1是一示例性实施例提供的一种构建客户端的项目结构示意图;
图2是一示例性实施例提供的一种客户端逻辑更新的流程示意图;
图3是一示例性实施例提供的一种客户端逻辑更新方法的流程图;
图4是一示例性的实施例提供的一种调用共享接口的流程示意图;
图5是一示例性实施例提供的一种客户端逻辑更新装置的框图;
图6是一示例性实施例提供的一种客户端逻辑更新方法对应的可读存储介质的示意图;
图7是一示例性实施例提供的一种能够实现上述方法的电子设备的示意图。
在附图中,相同或对应的标号表示相同或对应的部分。
具体实施方式
下面将参考若干示例性实施方式来描述本公开的原理和精神。应当理解,给出这些实施方式仅仅是为了使本领域技术人员能够更好地理解进而实现本公开,而并非以任何方式限制本公开的范围。相反,提供这些实施方式是为了使本公开更加透彻和完整,并且能够将本公开的范围完整地传达给本领域的技术人员。
本领域技术人员知道,本公开的实施方式可以实现为一种系统、装置、设备、方法或计算机可读存储介质。因此,本公开可以具体实现为以下形式,即:完全的硬件、完全的软件(包括固件、驻留软件、微代码等),或者硬件和软件结合的形式。
根据本公开的实施方式,提出了一种客户端逻辑更新方法、装置、电子设备及计算机可读存储介质。
在本文中,需要理解的是,附图中的任何元素数量均用于示例而非限制,以及任何命名都仅用于区分,而不具有任何限制含义。并且,本公开所涉及的数据可以为经用户授权或者经过各方充分授权的数据。
下面参考本公开的若干代表性实施方式,详细阐释本公开的原理和精神。
应用场景总览
原生开发(Native App开发),是指为特定平台开发应用程序时,可以利用该平台提供的开发框架、开发语言、开发类库进行开发。运用原生技术开发的应用程序,通常具备响应速度快、兼容性高、安全性高等特点。
在针对已发布的原生开发应用程序进行客户端逻辑更新的场景中,通常需要重新发布应用程序的新版本,以使用户可以通过应用市场或已安装的应用程序的旧版本客户端,下载并安装新版本客户端,来更新应用程序的客户端逻辑。
由此可见,受限于应用市场的上架流程、用户的更新行为等因素,原生开发应用程序的客户端逻辑难以及时进行更新。
为了及时地针对原生开发应用程序进行客户端逻辑更新,在一个相关的实施例中,在运用原生技术开发应用程序的过程中,可以将后续可能会改变的客户端逻辑转移到后端,也即,可以将后续可能会改变的客户端逻辑开发为由应用程序的服务端提供的功能接口,使得客户端可以通过调用由服务端提供的功能接口来实现相应的功能,而无需本地执行所述客户端逻辑;通过以上方式,只需要在应用程序的服务端提供与更新后的客户端逻辑对应的新版本功能接口,并且客户端只需要改为调用由服务端提供的新版本功能接口,就可以在无需客户端重新发版的情况下,实现客户端逻辑更新。
需要说明的是,在以上示出的实施例中,在一些交互性较强的业务场景中,客户端可能需要频繁地访问后端,造成业务响应速度下降、用户体验变差等问题。
在另一个相关的实施例中,针对已经发布的原生开发应用程序,可以基于JavaScript编写与待更新的客户端逻辑对应的程序代码,并下发给应用程序的客户端,使得客户端可以基于内置的JavaScript引擎执行所述与待更新的客户端逻辑对应的程序代码;通过以上方式,可以在无需客户端重新发版的情况下,实现客户端逻辑的动态化更新。
需要说明的是,在以上示出的实施例中,由于与动态下发的客户端逻辑对应的程序代码是基于JavaScript编写的,而与原生开发的其他客户端逻辑对应的程序代码通常是基于C/C++等原生开发语言编写的,编程语言存在差异;因此,开发人员在编写与动态下发的客户端逻辑对应的程序代码的过程中,还需要通过文档统一约定各个接口分别在原生(Native)侧与JS(JavaScript)侧的定义与使用方式,还需要考虑函数参数、返回值的编码与解码等桥接细节,并需要编写相应的转换代码,造成开发效率较低、对开发人员的技术水平要求较高等问题。
由此可见,在针对已发布的原生开发应用程序进行客户端逻辑更新的场景中,难以同时保证客户端逻辑的更新及时性、执行高性能与开发效率。
需要注意的是,上述应用场景仅是为了便于理解本公开的精神和原理而示出,本公开的实施方式在此方面不受任何限制。相反,本公开的实施方式可以应用于适用的任何场景。
发明概述
有鉴于此,本公开提供一种通过基于Kotlin语言编写的与待更新的客户端逻辑对应的程序代码,针对原生开发的应用程序的客户端逻辑进行动态化更新的技术方案。
其中,Kotlin是一种用于多平台开发的静态编程语言。由于基于Kotlin语言编写的程序代码,可以被编译为与平台无关的Java字节码(byte code),以由JVM(Java VirtualMachine,Java虚拟机)解释执行,也可以被编译为JavaScript,以便于在没有JVM的设备上运行,也可以被编译为与某个平台对应的二进制代码(machine code),以直接在机器上运行;因此,基于Kotlin语言编写的程序代码可以被JVM、JS、Native三个平台共享。
在一些可能的实施方式中,通过Kotlin Multiplatform,可以先基于Kotlin语言编写源码,再将其编译为目标平台代码,从而实现跨平台应用开发。
本公开的核心构思在于:
针对原生开发的应用程序,响应于确定所述应用程序的客户端逻辑待更新,可以获取与待更新的客户端逻辑对应的插件程序的程序代码文件;其中,所述应用程序与所述插件程序之间的共享接口是基于Kotlin语言定义的;进一步地,可以根据获取到的程序代码文件,将所述插件程序加载至所述应用程序;进一步地,可以执行所述插件程序,以实现与所述插件程序对应的客户端逻辑。
需要说明的是,在本公开的实施例中,所述与待更新的客户端逻辑对应的插件程序,也可以被称作动态化程序,在此不做特别限定。
例如,请参见图1,图1是一示例性实施例提供的一种构建客户端的项目结构示意图。如图1所示,可以在commonMain目录中,通过Kotlin Multiplatform定义应用程序的原生侧与JS侧之间的共享接口,也即,定义原生开发的应用程序与动态下发的插件程序之间的共享接口与数据模型;以及,可以在hostMain目录中,编写应用程序的原生开发的客户端逻辑;以及,可以在jsMain目录中,基于Kotlin/JS编写可动态下发的客户端逻辑;其中,所述hostMain目录和所述jsMain目录均依赖于所述commonMain目录,以共享在所述commonMain目录中定义的接口与数据模型;所述hostMain目录和所述jsMain目录可以互为共享接口的实现方和使用方,并可以通过各自侧的运行时,注册与共享接口对应的接口实例和/或使用与共享接口对应的接口实例。
在图1的基础上,请参见图2,图2是一示例性实施例提供的一种客户端逻辑更新的流程示意图。如图2所示,可以通过Kotlin Multiplatform编写共享源码,也即定义应用程序的原生侧与JS侧之间的共享接口与数据模型;以及,可以在原生侧编写与原生开发的客户端逻辑对应的应用程序源码,并可以通过客户端构建工具,构建出应用程序的客户端(也即动态更新前的客户端);以及,可以在JS侧基于Kotlin/JS编写与可动态下发的客户端逻辑对应的插件程序源码;进一步地,针对已经发布的原生开发的应用程序,响应于确定所述应用程序的客户端逻辑待更新,所述应用程序的客户端可以获取与待更新的客户端逻辑对应的插件程序的程序代码文件(如源码文件、字节码文件等);进一步地,所述应用程序的客户端可以根据获取到的程序代码文件,基于客户端内嵌的JavaScript引擎将所述插件程序加载至所述应用程序,并可以基于JavaScript引擎执行所述插件程序,以实现与所述插件程序对应的客户端逻辑,也即,实现了更新后的客户端逻辑。
需要说明的是,关于客户端内嵌的JavaScript引擎具体是何种引擎,在本公开的实施例中不做特别限定。例如,客户端具体可以采用但不限于V8、JavaScriptCore、QuickJS、Rhino、Hermes等JavaScript引擎。
通过这种方式,一方面,由于可以将需要更新的部分客户端逻辑,以插件程序的形式动态加载至原生开发的应用程序,并可以基于客户端内嵌的JS引擎执行动态下发的插件程序,从而在无需客户端重新发版的情况下,能够针对已发布的原生开发的应用程序及时地进行客户端逻辑更新,同时可以保证客户端逻辑更新后的执行高性能。
另一方面,由于原生开发的应用程序与动态下发的插件程序之间的共享接口是基于Kotlin语言定义的,可以被JVM、JS、Native三个平台共享,因此开发人员在编写插件程序的程序代码的过程中,无需通过文档统一约定各个接口分别在原生侧与JS侧的定义与使用方式,无需过多考虑桥接细节,也无需编写相应的转换代码,从而在针对已发布的原生开发应用程序进行客户端逻辑更新的场景中,能够同时保证客户端逻辑的更新及时性与开发高效性。
示例性方法
下面将通过具体的实施例对本说明书的技术构思进行详细描述。
在本公开的一个实施例中,可以将暂时不需要更新的部分客户端逻辑,基于Kotlin/Native进行开发,以及,可以将后续需要更新的另一部分客户端逻辑,基于Kotlin/JS以插件程序的形式进行开发;在需要针对已发布的原生开发的应用程序进行客户端逻辑更新的场景中,无需客户端重新发版,只需动态下发所述插件程序,进而可以将所述插件程序动态加载至原生开发的应用程序,并可以基于客户端内嵌的JavaScript引擎执行所述插件程序,以实现更新后的客户端逻辑。
请参见图3,图3是一示例性实施例提供的一种客户端逻辑更新方法的流程图。所述方法可以应用于应用程序的客户端。所述方法可以包括以下步骤:
步骤302:响应于确定应用程序的客户端逻辑待更新,获取与待更新的客户端逻辑对应的插件程序的程序代码文件;其中,所述应用程序与所述插件程序之间的共享接口是基于Kotlin语言定义的。
例如,如图2所示,可以通过Kotlin Multiplatform,定义应用程序的原生侧与JS侧之间的共享接口与数据模型;以及,可以在原生侧编写与原生开发的客户端逻辑对应的应用程序源码,并可以通过客户端构建工具,构建出应用程序的客户端;以及,可以在JS侧基于Kotlin/JS编写与可动态下发的客户端逻辑对应的插件程序源码;进一步地,响应于确定所述应用程序的客户端逻辑待更新,所述应用程序的客户端可以获取与待更新的客户端逻辑对应的插件程序的程序代码文件(如源码文件、字节码文件等)。
在一些可能的实施方式中,在所述步骤302中,所述客户端可以根据从服务端获取到的程序清单,确定所述应用程序的客户端逻辑是否需要进行更新。在响应于确定应用程序的客户端逻辑待更新,获取与待更新的客户端逻辑对应的插件程序的程序代码文件之前,所述方法还可以包括:
步骤308:从所述应用程序的服务端获取程序清单;其中,所述程序清单包括所述插件程序所包含的至少一个功能模块的模块信息,和所述至少一个功能模块所依赖的其他功能模块的模块信息;
步骤310:确定获取到的程序清单所包括的模块信息与上一次获取到的程序清单所包括的模块信息是否一致;
步骤312:如果获取到的程序清单所包括的模块信息与上一次获取到的程序清单所包括的模块信息不一致,则确定所述应用程序的客户端逻辑待更新。
例如,如图2所示,根据在JS侧基于Kotlin/JS编写的插件程序源码,以及JS侧运行时依赖,可以生成所述插件程序的程序代码文件和所述插件程序的程序清单;其中,所述程序清单至少可以包括所述插件所包含的至少一个功能模块的模块信息,以及所述至少一个功能模块所依赖的其他功能模块的模块信息。所述客户端可以从所述应用程序的服务端定时地或周期性地获取最新生成的程序清单,并可以将本次获取到的程序清单与上一次获取到的程序清单进行比较,确定本次获取到的程序清单所包括的模块信息与上一次获取到的程序清单所包括的模块信息是否一致;如果不一致,则可以确定所述应用程序的客户端逻辑待更新。
其中,在所述步骤308中,所述从所述应用程序的服务端获取程序清单,具体可以包括:从CDN(Content Delivery Network,内容分发网络)下载所述程序清单。
例如,所述客户端可以根据用户指定的URL(uniform resource locator,统一资源定位符),从CDN将程序清单(如:manifest.json文件)下载至本地,并可以使用kotlinx-serialization-json库来解析获取到的manifest.json文件,得到所述程序清单所包括的模块信息,还可以按照各个功能模块之间的依赖关系拓扑排序。
在一个可能的实施例中,在所述步骤308中,所述程序清单具体可以包括:所述插件程序的入口函数,所述插件程序所包含的至少一个功能模块的模块信息,以及所述至少一个功能模块所依赖的其他功能模块的模块信息。其中,各个功能模块的模块信息,具体可以包括:模块标识,以及本功能模块所依赖的其他功能模块的模块标识。
例如,请参见表1,表1是一示例性实施例提供的一种程序清单的格式定义表。
表1
以及,请参见表2,表2是一示例性实施例提供的一种模块信息的格式定义表。
表2
请结合如表1和表2所示的格式定义,所述客户端获取到的manifest.json文件可以如下所示:
在以上示出的manifest.json文件中,所述插件程序包含有模块标识为“kotlin-kotlin-stdlib-js-ir.js”、“runtime.js”、“sample.js”的功能模块,这三个功能模块的依赖顺序为“sample.js”->“runtime.js”->“kotlin-kotlin-stdlib-js-ir.js”;所述插件程序的入口函数的函数标识为“com.sample.main”,所述插件程序的入口函数所在的功能模块的模块标识为“sample.js”。
在这种情况下,在所述步骤302中,所述获取与待更新的客户端逻辑对应的插件程序的程序代码文件,具体可以包括:根据获取到的程序清单所包括的模块信息,下载与所述插件程序所包含的至少一个功能模块对应的程序代码文件,以及下载与所述至少一个功能模块所依赖的其他功能模块对应的程序代码文件。
例如,接着以上示出的实施例继续举例说明,如果确定所述应用程序的客户端逻辑待更新,则所述客户端可以根据如上所示的manifest.json文件,下载与所述插件程序所包含的模块标识为“kotlin-kotlin-stdlib-js-ir.js”、“runtime.js”、“sample.js”的功能模块对应的程序代码文件。
在一个可能的实施例中,各个功能模块的模块信息,具体还可以包括:与功能模块对应的程序代码文件的哈希值。在这种情况下,在根据获取到的程序代码文件,将所述插件程序加载至所述应用程序之前,所述方法还可以包括:响应于所述程序代码文件下载完成,计算下载完成的所述程序代码文件的哈希值;确定获取到的程序清单中的哈希值与计算得到的哈希值是否一致;如果获取到的程序清单中的哈希值与计算得到的哈希值一致,则针对下载完成的所述程序代码文件进行完整性校验通过。
例如,接着以上示出的实施例继续举例说明,在根据如上所示的manifest.json文件,下载与模块标识为“sample.js”的功能模块对应的程序代码文件之后,响应于所述程序代码文件下载完成,所述客户端可以计算下载完成的所述程序代码文件的SHA256摘要;进一步地,可以确定获取到的manifest.json文件中与该功能模块对应的程序代码文件的SHA256摘要“aba5e1bff6b4a3c59b0e...”与计算得到的SHA256摘要是否一致;如果一致,则针对下载完成的与模块标识为“sample.js”的功能模块对应的程序代码文件进行完整性校验通过;通过类似的过程,所述客户端还可以针对下载完成的与模块标识为“kotlin-kotlin-stdlib-js-ir.js”、“runtime.js”的功能模块对应的程序代码文件进行完整性校验,在此不再一一赘述。
步骤304:根据获取到的程序代码文件,将所述插件程序加载至所述应用程序。
例如,在获取到与待更新的客户端逻辑对应的插件程序的程序代码文件之后,所述客户端可以基于内嵌的JS引擎,按照所述插件程序所包括的各个功能模块之间的依赖关系,加载获取到的所述插件程序的程序代码文件。
接着以上示出的实施例继续举例说明,根据获取到的所述插件程序的程序代码文件,由于所述插件程序包含有模块标识为“kotlin-kotlin-stdlib-js-ir.js”、“runtime.js”、“sample.js”的功能模块,这三个功能模块的依赖顺序为“sample.js”->“runtime.js”->“kotlin-kotlin-stdlib-js-ir.js”,因此可以按照所述依赖顺序加载获取到的所述插件程序的程序代码文件。
在一些可能的实施方式中,在所述步骤304中,所述根据获取到的程序代码文件,将所述插件程序加载至所述应用程序,具体可以包括:根据获取到的程序代码文件,基于QuickJS引擎将所述插件程序加载至所述应用程序。
在这种情况下,所述获取到的程序代码文件,具体可以包括:与待更新的客户端逻辑对应的插件程序的字节码文件;其中,所述插件程序的字节码文件,可以包括针对基于Kotlin语言编写的所述插件程序的源码文件进行编译而得到的所述插件程序的QuickJS字节码文件。
需要说明的是,在以上示出的实施方式中,一方面,由于QuickJS引擎是一个包含js的编译器和解释器的轻量js引擎,具备体积小、启动快、解释执行速度快的优点,因此相较于其他JavaScript引擎,基于QuickJS引擎将所述插件程序加载至所述应用程序,可以提高客户端逻辑动态化更新的效率。
另一方面,在基于QuickJS引擎加载、执行所述插件程序的基础上,通过先将基于Kotlin语言编写的所述插件程序的源码文件编译为字节码文件,再将QuickJS字节码文件动态下发给所述应用程序的客户端,客户端在获取到QuickJS字节码文件之后无需执行编译过程,可以进一步提高客户端逻辑动态化更新的效率。
步骤306:执行所述插件程序,以实现与所述插件程序对应的客户端逻辑。
例如,在将所述插件程序加载至所述应用程序之后,所述客户端可以基于所述JS引擎,执行所述插件程序的入口函数,以实现与所述插件程序对应的客户端逻辑。
接着以上示出的实施例继续举例说明,在将所述插件程序加载至所述应用程序之后,所述客户端可以基于内嵌的JavaScript引擎,执行函数标识为“com.sample.main”的入口函数。
在本公开实施例中,针对基于Kotlin语言定义的共享接口,所述应用程序的JS侧与原生侧可以互为所述共享接口的实现方和使用方,并可以通过各自侧的运行时注册和/或使用所述共享接口。
为了使本领域技术人员更好地理解本公开中的实施例,下面先结合图4,以在JS侧实现所述共享接口并在原生侧使用所述共享接口为例,通过具体实施例介绍所述共享接口的定义、实现与使用过程。
首先,可以先在如图1所示的commonMain目录中,通过Kotlin Multiplatform定义应用程序的原生侧与JS侧之间的共享接口和数据模型,还可以基于Kotlin编译器插件自动生成封装有桥接功能的实现类(也即桥接类),所述实现类可以继承定义的所述共享接口;如下所示:
进一步地,可以在如图1所示的jsMain目录中,实现所述共享接口(也即注册与所述共享接口对应的接口实例),并注册与所述共享接口对应的桥接类实例;如下所示:
进一步地,可以在如图1所示的hostMain目录中,获取与所述共享接口对应的桥接类实例;如下所示:
//在原生侧获取与共享接口对应的桥接类实例
val sampleService=registry.get<SampleService>("SampleService")
请参见图4,图4是一示例性的实施例提供的一种调用共享接口的流程示意图。当使用方请求调用所述共享接口时,可以获得自动生成的与所述共享接口对应的桥接类实例,所述桥接类实例可以作为真实的共享接口实例在使用侧的代理,使用方通过调用所述桥接类实例的方法,可以获得实现侧真实的能力。
例如,如图4所示,所述应用程序的JS侧可以作为所述共享接口的实现方,以及,所述应用程序的原生侧可以作为所述共享接口的使用方;原生侧可以获取在JS侧注册的与所述共享接口对应的第一类桥接类实例,并可以调用所述第一类桥接类实例(中定义的函数);以使JS侧可以响应于所述第一类桥接类实例被调用,执行所述第一类桥接类实例中定义的函数,并将调用结果返回原生侧。
具体地,请参见表3,表3是一示例性的实施例提供的一种调用信息封装的数据结构表,
表3
原生侧可以基于如表3所示的数据结构封装针对与所述共享接口对应的第一类桥接类实例的调用信息,并可以使用kotlinx-serialization-json库来将所述调用信息编码为JSON字符串;进一步地,原生侧可以将所述JSON字符串通过调用通道传递至JS侧;进一步地,JS侧可以使用kotlinx-serialization-json库来解码所述JSON字符串;进一步地,JS侧可以根据解码结果中的“serviceName”字段,在注册中心查找对应的第一类桥接类实例,并可以根据解码结果中的“function”字段和“args”字段,调用所述桥接类实例中定义的函数。
基于类似的过程,如图4所示,所述应用程序的原生侧可以作为所述共享接口的实现方,以及,所述应用程序的JS侧可以作为所述共享接口的使用方;JS侧可以获取在原生侧注册的与所述共享接口对应的第二类桥接类实例,并可以调用所述第二类桥接类实例(中定义的函数);以使原生侧可以响应于所述第二类桥接类实例被调用,执行所述第二类桥接类实例中定义的函数,并将调用结果返回JS侧。具体调用过程在此不再赘述。
在一些可能的实施方式中,可以在所述应用程序的原生侧使用JS侧的能力。在所述步骤306中,所述执行所述插件程序,具体可以包括:执行所述插件程序的入口函数,以获取在JS侧注册的与所述共享接口对应的第一类桥接类实例,并调用所述第一类桥接类实例;其中,所述第一类桥接类实例包括:响应于在JS侧注册与所述共享接口对应的接口实例,在JS侧注册的与所述共享接口的桥接类对应的桥接类实例;所述桥接类为响应于基于Kotlin语言定义所述共享接口,通过继承所述共享接口而生成的。
例如,由于在所述插件程序的程序代码文件中,所述插件程序与所述应用程序之间的共享接口是基于Kotlin语言定义的,并且,响应于基于Kotlin语言定义所述共享接口,可以通过继承所述共享接口自动生成与共享接口对应的桥接类;响应于在JS侧注册与所述共享接口对应的接口实例,可以在JS侧注册与所述共享接口的桥接类对应的桥接类实例,并可以将在JS侧注册的桥接类实例确定为与所述共享接口对应的第一类桥接类实例;因此,响应于所述客户端执行所述插件程序的入口函数,所述客户端(也即原生侧)可以获取与所述共享接口对应的第一类桥接类实例,并可以调用所述第一类桥接类实例,以使JS侧响应于所述第一类桥接类实例被调用,执行所述第一类桥接类实例中定义的函数,并将调用结果返回给原生侧。
在另一些可能的实施方式中,可以在所述应用程序的JS侧使用原生侧的能力。所述方法还可以包括:响应于在原生侧注册与所述共享接口对应的接口实例,在原生侧注册与所述共享接口的桥接类对应的桥接类实例,并将在原生侧注册的桥接类实例确定为与所述共享接口对应的第二类桥接类实例;响应于所述第二类桥接类实例被调用,执行所述第二类桥接类实例中定义的函数。
例如,响应于在原生侧注册与所述共享接口对应的接口实例,可以在原生侧注册与所述共享接口的桥接类对应的桥接类实例,并可以将在原生侧注册的桥接类实例确定为与所述共享接口对应的第二类桥接类实例;因此,所述应用程序的JS侧可以获取与所述共享接口对应的第二类桥接类实例,并可以调用所述第二类桥接类实例,以使原生侧响应于所述第二类桥接类实例被调用,执行所述第二类桥接类实例中定义的函数,并将调用结果返回给JS侧。
需要说明的是,在以上示出的实施例中,由于响应于所述共享接口被定义,可以自动生成与所述共享接口对应的桥接类,后续响应于在实现方一侧注册与共享接口对应的接口实例,就可以在实现方一侧注册与共享接口的桥接类对应的桥接类实例,因此,开发人员在编写所述插件程序的程序代码的过程中,无需过多关注桥接细节,从而提高了开发效率。
在以上实施例中,一方面,由于可以将需要更新的部分客户端逻辑,以插件程序的形式动态加载至原生开发的应用程序,并可以基于客户端内嵌的JS引擎执行动态下发的插件程序,从而在无需客户端重新发版的情况下,能够针对已发布的原生开发的应用程序及时地进行客户端逻辑更新,同时可以保证客户端逻辑更新后的执行高性能。
另一方面,由于原生开发的应用程序与动态下发的插件程序之间的共享接口是基于Kotlin语言定义的,可以被JVM、JS、Native三个平台共享,因此开发人员在编写插件程序的程序代码的过程中,无需通过文档统一约定各个接口分别在原生侧与JS侧的定义与使用方式,无需过多考虑桥接细节,也无需编写相应的转换代码,从而在针对已发布的原生开发应用程序进行客户端逻辑更新的场景中,能够同时保证客户端逻辑的更新及时性与开发高效性。
示例性装置
在本公开的示例性实施例中,还提供了一种客户端逻辑更新装置。
请参见图5,图5是一示例性实施例提供的一种客户端逻辑更新装置的框图。
如图5所示,客户端逻辑更新装置500可以包括:第一获取模块502、加载模块504和执行模块506。其中:
第一获取模块502,用于响应于确定应用程序的客户端逻辑待更新,获取与待更新的客户端逻辑对应的插件程序的程序代码文件;其中,所述应用程序与所述插件程序之间的共享接口是基于Kotlin语言定义的;
加载模块504,用于根据获取到的程序代码文件,将所述插件程序加载至所述应用程序;
执行模块506,用于执行所述插件程序,以实现与所述插件程序对应的客户端逻辑。
在一实施例中,客户端逻辑更新装置500还包括:
第二获取模块,用于从所述应用程序的服务端获取程序清单;其中,所述程序清单包括所述插件程序所包含的至少一个功能模块的模块信息,和所述至少一个功能模块所依赖的其他功能模块的模块信息;
确定模块,用于确定获取到的程序清单所包括的模块信息与上一次获取到的程序清单所包括的模块信息是否一致;如果获取到的程序清单所包括的模块信息与上一次获取到的程序清单所包括的模块信息不一致,则确定所述应用程序的客户端逻辑待更新。
在一实施例中,所述第一获取模块502,具体用于:
根据获取到的程序清单所包括的模块信息,下载与所述插件程序所包含的至少一个功能模块对应的程序代码文件,以及下载与所述至少一个功能模块所依赖的其他功能模块对应的程序代码文件。
在一实施例中,所述模块信息包括与功能模块对应的程序代码文件的哈希值;
客户端逻辑更新装置500还包括:
计算模块,用于响应于所述程序代码文件下载完成,计算下载完成的所述程序代码文件的哈希值;
校验模块,用于确定获取到的程序清单中的哈希值与计算得到的哈希值是否一致;如果获取到的程序清单中的哈希值与计算得到的哈希值一致,则针对下载完成的所述程序代码文件进行完整性校验通过。
在一实施例中,所述加载模块504,具体用于:
根据获取到的程序代码文件,基于QuickJS引擎将所述插件程序加载至所述应用程序。
在一实施例中,所述获取到的程序代码文件,包括:与待更新的客户端逻辑对应的插件程序的字节码文件;其中,所述插件程序的字节码文件,包括针对基于Kotlin语言编写的所述插件程序的源码文件进行编译而得到的所述插件程序的QuickJS字节码文件。
在一实施例中,所述程序清单包括所述插件程序的入口函数;
所述执行模块506,具体用于:
执行所述插件程序的入口函数,以获取在JS侧注册的与所述共享接口对应的第一类桥接类实例,并调用所述第一类桥接类实例;其中,所述第一类桥接类实例包括:响应于在JS侧注册与所述共享接口对应的接口实例,在JS侧注册的与所述共享接口的桥接类对应的桥接类实例;所述桥接类为响应于基于Kotlin语言定义所述共享接口,通过继承所述共享接口而生成的。
在一实施例中,客户端逻辑更新装置500还包括:
生成模块,用于响应于在原生侧注册与所述共享接口对应的接口实例,在原生侧注册与所述共享接口的桥接类对应的桥接类实例,并将在原生侧注册的桥接类实例确定为与所述共享接口对应的第二类桥接类实例;
所述执行模块506,还用于响应于所述第二类桥接类实例被调用,执行所述第二类桥接类实例中定义的函数。
上述客户端逻辑更新装置500的各个模块的具体细节,已经在之前描述客户端逻辑更新方法流程中进行了详细的描述,因此,此处不再赘述。
应当注意,尽管在上文详细描述中提及客户端逻辑更新装置500的若干模块或者单元,但是这种划分并非强制性的。实际上,根据本公开的实施方式,上文描述的两个或更多模块或者单元的特征和功能可以在一个模块或者单元中具体化。反之,上文描述的一个模块或者单元的特征和功能可以进一步划分为由多个模块或者单元来具体化。
示例性介质
在本公开的示例性实施例中,还提供了一种计算机可读存储介质,其上存储有能够实现本说明书上述方法的程序产品。在一些可能的实施例中,本公开的各个方面还可以实现为一种程序产品的形式,其包括程序代码,当所述程序产品在终端设备上运行时,所述程序代码用于使所述终端设备执行本说明书上述“示例性方法”部分中描述的根据本公开各种示例性实施例的步骤。
请参见图6,图6是一示例性实施例提供的一种客户端逻辑更新方法对应的可读存储介质的示意图。
参考图6所示,描述了根据本公开的实施例的用于实现上述方法的可读存储介质600,其可以采用便携式紧凑盘只读存储器(CD-ROM)并包括程序代码,并可以在终端设备,例如个人电脑上运行。然而,本公开的可读存储介质不限于此,在本公开中,可读存储介质可以是任何包含或存储程序的有形介质,该程序可以被指令执行系统、装置或者器件使用或者与其结合使用。
所述可读存储介质可以采用一个或多个可读介质的任意组合。可读介质可以是可读信号介质或者可读存储介质。可读存储介质例如可以为但不限于电、磁、光、电磁、红外线、或半导体的系统、装置或器件,或者任意以上的组合。可读存储介质的更具体的例子(非穷举的列表)包括:具有一个或多个导线的电连接、便携式盘、硬盘、随机存取存储器(RAM)、只读存储器(ROM)、可擦式可编程只读存储器(EPROM或闪存)、光纤、便携式紧凑盘只读存储器(CD-ROM)、光存储器件、磁存储器件、或者上述的任意合适的组合。
计算机可读信号介质可以包括在基带中或者作为载波一部分传播的数据信号,其中承载了可读程序代码。这种传播的数据信号可以采用多种形式,包括但不限于电磁信号、光信号或上述的任意合适的组合。可读信号介质还可以是可读存储介质以外的任何可读介质,该可读介质可以发送、传播或者传输用于由指令执行系统、装置或者器件使用或者与其结合使用的程序。
可读介质上包含的程序代码可以用任何适当的介质传输,包括但不限于无线、有线、光缆、RF等等,或者上述的任意合适的组合。
可以以一种或多种程序设计语言的任意组合来编写用于执行本公开操作的程序代码,所述程序设计语言包括面向对象的程序设计语言—诸如Java、C++等,还包括常规的过程式程序设计语言—诸如“C”语言或类似的程序设计语言。程序代码可以完全地在用户计算设备上执行、部分地在用户设备上执行、作为一个独立的软件包执行、部分在用户计算设备上部分在远程计算设备上执行、或者完全在远程计算设备或服务器上执行。在涉及远程计算设备的情形中,远程计算设备可以通过任意种类的网络,包括局域网(LAN)或广域网(WAN),连接到用户计算设备,或者,可以连接到外部计算设备(例如利用因特网服务提供商来通过因特网连接)。
示例性电子设备
在本公开的示例性实施例中,还提供了一种能够实现上述客户端逻辑更新方法的电子设备。
请参见图7,图7是一示例性实施例提供的一种能够实现上述方法的电子设备的示意图。
下面参照图7来描述根据本公开的这种实施例的电子设备700。图7显示的电子设备700仅仅是一个示例,不应对本公开实施例的功能和使用范围带来任何限制。
如图7所示,电子设备700以通用计算设备的形式表现。电子设备700的组件可以包括但不限于:上述至少一个处理单元701、上述至少一个存储单元702、连接不同系统组件(包括存储单元702和处理单元701)的总线703。
其中,所述存储单元存储有程序代码,所述程序代码可以被所述处理单元701执行,使得所述处理单元701执行本说明书上述各种实施例的步骤。
存储单元702可以包括易失性存储单元形式的可读介质,例如随机存取存储单元(RAM)7021和/或高速缓存存储单元7022,还可以进一步包括只读存储单元(ROM)7023。
存储单元702还可以包括具有一组(至少一个)程序模块7025的程序/使用工具7024,这样的程序模块7025包括但不限于:操作系统、一个或者多个应用程序、其它程序模块以及程序数据,这些示例中的每一个或某种组合中可能包含网络环境的现实。
总线703可以为表示几类总线结构中的一种或多种,包括存储单元总线或者存储单元控制器、外围总线、图形加速端口、处理单元或者使用多种总线结构中的任意总线结构的局域总线。
电子设备700也可以与一个或多个外部设备704(例如键盘、指向设备、蓝牙设备等)通信,还可与一个或者多个使得用户能与该电子设备700交互的设备通信,和/或与使得该电子设备700能与一个或多个其它计算设备进行通信的任何设备(例如路由器、调制解调器等等)通信。这种通信可以通过输入/输出(I/O)接口705进行。并且,电子设备700还可以通过网络适配器706与一个或者多个网络(例如局域网(LAN),广域网(WAN)和/或公共网络,例如因特网)通信。如图所示,网络适配器706通过总线703与电子设备700的其它模块通信。应当明白,尽管图7中未示出,可以结合电子设备700使用其它硬件和/或软件模块,包括但不限于:微代码、设备驱动器、冗余处理单元、外部磁盘驱动阵列、RAID系统、磁带驱动器以及数据备份存储系统等。
通过以上的实施例的描述,本领域的技术人员易于理解,这里描述的示例实施例可以通过软件实现,也可以通过软件结合必要的硬件的方式来实现。因此,根据本公开实施例的技术方案可以以软件产品的形式体现出来,该软件产品可以存储在一个非易失性存储介质(可以是CD-ROM,U盘,移动硬盘等)中或网络上,包括若干指令以使得一台计算设备(可以是个人计算机、服务器、终端装置、或者网络设备等)执行根据本公开实施例的方法。
本领域技术人员在考虑说明书及实践这里公开的公开后,将容易想到本公开的其他实施例。本申请旨在涵盖本公开的任何变型、用途或者适应性变化,这些变型、用途或者适应性变化遵循本公开的一般性原理并包括本公开未公开的本技术领域中的公知常识或惯用技术手段。说明书和实施例仅被视为示例性的,本公开的真正范围和精神由权利要求指出。
应当注意,尽管在上文详细描述中提及了装置的若干单元/模块或子单元/模块,但是这种划分仅仅是示例性的并非强制性的。实际上,根据本公开的实施方式,上文描述的两个或更多单元/模块的特征和功能可以在一个单元/模块中具体化。反之,上文描述的一个单元/模块的特征和功能可以进一步划分为由多个单元/模块来具体化。
此外,尽管在附图中以特定顺序描述了本公开方法的操作,但是,这并非要求或者暗示必须按照该特定顺序来执行这些操作,或是必须执行全部所示的操作才能实现期望的结果。附加地或备选地,可以省略某些步骤,将多个步骤合并为一个步骤执行,和/或将一个步骤分解为多个步骤执行。
虽然已经参考若干具体实施方式描述了本公开的精神和原理,但是应该理解,本公开并不限于所公开的具体实施方式,对各方面的划分也不意味着这些方面中的特征不能组合以进行受益,这种划分仅是为了表述的方便。本公开旨在涵盖所附权利要求的精神和范围内所包括的各种修改和等同布置。
Claims (10)
1.一种客户端逻辑更新方法,所述方法包括:
响应于确定应用程序的客户端逻辑待更新,获取与待更新的客户端逻辑对应的插件程序的程序代码文件;其中,所述应用程序与所述插件程序之间的共享接口是基于Kotlin语言定义的;
根据获取到的程序代码文件,将所述插件程序加载至所述应用程序;
执行所述插件程序,以实现与所述插件程序对应的客户端逻辑。
2.根据权利要求1所述的方法,在响应于确定应用程序的客户端逻辑待更新,获取与待更新的客户端逻辑对应的插件程序的程序代码文件之前,所述方法还包括:
从所述应用程序的服务端获取程序清单;其中,所述程序清单包括所述插件程序所包含的至少一个功能模块的模块信息,和所述至少一个功能模块所依赖的其他功能模块的模块信息;
确定获取到的程序清单所包括的模块信息与上一次获取到的程序清单所包括的模块信息是否一致;
如果获取到的程序清单所包括的模块信息与上一次获取到的程序清单所包括的模块信息不一致,则确定所述应用程序的客户端逻辑待更新。
3.根据权利要求2所述的方法,所述获取与待更新的客户端逻辑对应的插件程序的程序代码文件,包括:
根据获取到的程序清单所包括的模块信息,下载与所述插件程序所包含的至少一个功能模块对应的程序代码文件,以及下载与所述至少一个功能模块所依赖的其他功能模块对应的程序代码文件。
4.根据权利要求1所述的方法,所述根据获取到的程序代码文件,将所述插件程序加载至所述应用程序,包括:
根据获取到的程序代码文件,基于QuickJS引擎将所述插件程序加载至所述应用程序。
5.根据权利要求4所述的方法,所述获取到的程序代码文件,包括:与待更新的客户端逻辑对应的插件程序的字节码文件;其中,所述插件程序的字节码文件,包括针对基于Kotlin语言编写的所述插件程序的源码文件进行编译而得到的所述插件程序的QuickJS字节码文件。
6.根据权利要求2所述的方法,所述程序清单包括所述插件程序的入口函数;
所述执行所述插件程序,包括:
执行所述插件程序的入口函数,以获取在JS侧注册的与所述共享接口对应的第一类桥接类实例,并调用所述第一类桥接类实例;其中,所述第一类桥接类实例包括:响应于在JS侧注册与所述共享接口对应的接口实例,在JS侧注册的与所述共享接口的桥接类对应的桥接类实例;所述桥接类为响应于基于Kotlin语言定义所述共享接口,通过继承所述共享接口而生成的。
7.根据权利要求6所述的方法,所述方法还包括:
响应于在原生侧注册与所述共享接口对应的接口实例,在原生侧注册与所述共享接口的桥接类对应的桥接类实例,并将在原生侧注册的桥接类实例确定为与所述共享接口对应的第二类桥接类实例;
响应于所述第二类桥接类实例被调用,执行所述第二类桥接类实例中定义的函数。
8.一种客户端逻辑更新装置,所述装置包括:
第一获取模块,用于响应于确定应用程序的客户端逻辑待更新,获取与待更新的客户端逻辑对应的插件程序的程序代码文件;其中,所述应用程序与所述插件程序之间的共享接口是基于Kotlin语言定义的;
加载模块,用于根据获取到的程序代码文件,将所述插件程序加载至所述应用程序;
执行模块,用于执行所述插件程序,以实现与所述插件程序对应的客户端逻辑。
9.一种电子设备,包括:
处理器;
用于存储所述处理器可执行指令的存储器;
其中,所述处理器被配置为执行上述权利要求1-7中任一所述的方法。
10.一种计算机可读存储介质,其上存储有计算机程序,该程序被处理器执行时实现上述权利要求1-7中任一所述的方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211504405.XA CN115934123A (zh) | 2022-11-28 | 2022-11-28 | 一种客户端逻辑更新方法、装置、电子设备及存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211504405.XA CN115934123A (zh) | 2022-11-28 | 2022-11-28 | 一种客户端逻辑更新方法、装置、电子设备及存储介质 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN115934123A true CN115934123A (zh) | 2023-04-07 |
Family
ID=86698696
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202211504405.XA Pending CN115934123A (zh) | 2022-11-28 | 2022-11-28 | 一种客户端逻辑更新方法、装置、电子设备及存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN115934123A (zh) |
-
2022
- 2022-11-28 CN CN202211504405.XA patent/CN115934123A/zh active Pending
Similar Documents
Publication | Publication Date | Title |
---|---|---|
JP6294886B2 (ja) | アプリケーション用の中間言語コードからネイティブコードを生成すること | |
US11550599B2 (en) | Method and apparatus for running applet | |
RU2658190C2 (ru) | Управление доступом во время выполнения к интерфейсам прикладного программирования | |
CN111367510B (zh) | 一种安卓功能模块开发的方法及装置 | |
US20210173665A1 (en) | Bootstrapping Profile-Guided Compilation and Verification | |
US11074154B2 (en) | Identifying a source file for use in debugging compiled code | |
CN111740948B (zh) | 数据包发布方法、动态更新方法、装置、设备及介质 | |
CN110140108B (zh) | 处理兄弟调用 | |
CN111026439B (zh) | 应用程序的兼容方法、装置、设备及计算机存储介质 | |
CN112769706B (zh) | 组件化路由方法及系统 | |
CN110865889A (zh) | 组件间传递事件的方法和装置 | |
CN110895471A (zh) | 安装包生成方法、装置、介质及电子设备 | |
CN111338623A (zh) | 一种开发用户界面的方法、装置、介质和电子设备 | |
CN111913741A (zh) | 对象拦截方法、装置、介质及电子设备 | |
US9756149B2 (en) | Machine-specific instruction set translation | |
CN113407165B (zh) | Sdk的生成和自升级方法、装置、可读介质和设备 | |
CN111338666A (zh) | 一种实现应用程序升级的方法、装置、介质和电子设备 | |
CN113138768A (zh) | 应用程序包生成方法、装置、电子设备以及可读存储介质 | |
CN116069366A (zh) | 客户端应用程序更新方法及装置、存储介质及电子设备 | |
CN115934123A (zh) | 一种客户端逻辑更新方法、装置、电子设备及存储介质 | |
CN111782196A (zh) | 基于mvp架构的开发方法及装置 | |
CN112379885A (zh) | 小程序编译方法、装置、设备及可读存储介质 | |
CN112068814A (zh) | 可执行文件的生成方法、装置、系统及介质 | |
CN115543486B (zh) | 面向无服务器计算的冷启动延迟优化方法、装置和设备 | |
CN111736841B (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 |