[0001]技术领域
[0002]本申请涉及计算机技术领域,尤其涉及一种埋点方法、装置、设备、存储介质及计算机程序产品。
[0003]背景技术
[0004]埋点分析是一种常用的数据采集方法,可对需要采集数据的“操作节点”进行埋点,以通过埋点收集“操作节点”所对应的用户数据。其中,操作节点指的是在应用程序或网站中,用户与界面进行交互的事件,例如,按钮点击、页面浏览、表单提交或视频播放等。
[0005]目前,在Android端新增埋点时,通常需要开发人员根据实际的埋点需求,在操作节点的程序代码中编写能够反映埋点需求的参数需求代码,并从埋点工具类中选取与埋点需求匹配的工具函数,同时在参数需求代码中配置该工具函数的调用逻辑,才能实现Android端新增埋点。
[0006]采用这种埋点方式新增埋点时,每次都需要开发人员基于自身经验手动选择与埋点需求适配的工具函数,并重新编写参数需求代码以及工具函数的调用逻辑,导致埋点效率较低。
[0007]发明内容
[0008]本申请的多个方面提供一种埋点方法、装置、设备、存储介质及计算机程序产品,用以更加方便、快捷地确定出埋点所需的工具函数,从而提高埋点效率。
[0009]本申请实施例提供一种埋点方法,包括:
[0010]在目标代码运行至预设函数的情况下,从所述目标代码中获取为所述预设函数添加的第一注解,所述预设函数为预先插入所述目标代码中且用于触发对所述第一注解对应的目标事件进行埋点的函数;
[0011]从所述第一注解中提取为所述目标事件配置的至少一条参数描述信息作为目标参数需求信息,所述参数描述信息用于描述所述目标事件所需的待采集参数;
[0012]基于参数需求信息与工具函数之间的映射关系,为所述目标事件确定在埋点后所需使用的至少一个目标工具函数,所述至少一个目标工具函数用于在所述目标事件埋点后采集所述目标事件对应的用户数据;
[0013]将所述至少一个目标工具函数添加到所述目标代码中所述目标事件对应的埋点位置,以实现在所述目标代码中对所述目标事件的埋点。
[0014]本申请实施例提供一种埋点装置,包括监测模块、控制模块和埋点模块;
[0015]所述监测模块,用于监测目标代码的运行进度,当监测到所述目标代码运行至预设函数时,向所述控制模块发送注解读取指令;
[0016]所述控制模块,用于接收所述监测模块发送的注解读取指令,从所述目标代码中获取为所述预设函数添加的第一注解,所述预设函数为预先插入所述目标代码中且用于触发对所述第一注解对应的目标事件进行埋点的函数;从所述第一注解中提取为所述目标事件配置的至少一条参数描述信息作为目标参数需求信息,将所述目标参数需求信息发送至所述埋点模块,其中,所述参数描述信息用于描述所述目标事件所需的待采集参数;
[0017]所述埋点模块,用于接收所述控制模块发送的目标参数需求信息,基于参数需求信息与工具函数之间的映射关系,为所述目标事件确定在埋点后所需使用的至少一个目标工具函数,所述至少一个目标工具函数用于在所述目标事件埋点后采集所述目标事件对应的用户数据;将所述至少一个目标工具函数添加到所述目标代码中所述目标事件对应的埋点位置,以实现在所述目标代码中对所述目标事件的埋点。
[0018]本申请实施例还提供一种计算设备,包括:存储器、处理器以及通信组件;
[0019]所述处理器与所述存储器和所述通信组件耦合,用于执行所述一条或多条计算机指令,以用于执行前述的埋点方法。
[0020]本申请实施例还提供一种存储计算机指令的计算机可读存储介质,当所述计算机指令被一个或多个处理器执行时,致使所述一个或多个处理器执行前述的埋点方法。
[0021]本申请实施例还提供一种计算机程序产品,包括计算机程序/指令;当计算机程序/指令被处理器执行时,致使所述处理器执行前述埋点方法。
[0022]在本申请实施例中,可基于埋点需求预先在目标代码中插入用于触发对第一注解对应的目标事件进行埋点的预设函数。埋点装置可在目标代码运行至预设函数的情况下,获取为预设函数添加的第一注解,并从第一注解中提取为目标事件配置的至少一条参数描述信息作为目标参数需求信息,参数描述信息用于描述目标事件所需的待采集参数。基于参数需求信息与工具函数之间的映射关系,可为目标事件确定与目标参数需求信息对应的至少一个目标工具函数,以用于在目标事件埋点后采集目标事件对应的用户数据,将至少一个目标工具函数添加到目标代码中目标事件对应的埋点位置,可实现对目标事件的埋点。
[0023]这样,可将目标参数需求信息的提取逻辑和目标工具函数的选取、调用逻辑,封装成通用埋点逻辑。在对目标事件埋点时,开发人员只需为预设函数配置第一注解,即可自动执行通用埋点逻辑:自动从第一注解中提取目标参数需求信息,无需人工编写参数需求代码;可基于参数需求信息与工具函数之间的映射关系自动选取目标工具函数,不再需要人工实时选择工具函数。并且,可将目标工具函数添加到目标代码中目标事件对应的埋点位置进行埋点,以在目标代码中将目标工具函数与目标事件进行关联,进而实现目标工具函数的调用逻辑的配置,而不再需要单独编写工具函数的调用逻辑。这大大减轻了开发人员的工作负担,缩短了为目标事件埋点所需耗费的时间,从而可有效提高埋点效率。
[0024]附图说明
[0025]此处所说明的附图用来提供对本申请的进一步理解,构成本申请的一部分,本申请的示意性实施例及其说明用于解释本申请,并不构成对本申请的不当限定。在附图中:
[0026]图1为本申请一示例性实施例提供的一种埋点方法的流程示意图;
[0027]图2为本申请一示例性实施例提供的一种埋点方法的逻辑示意图;
[0028]图3为本申请一示例性实施例提供的一种确定至少一个目标工具函数的流程图;
[0029]图4为本申请一示例性实施例提供的一种生成埋点文档的流程示意图;
[0030]图5为本申请一示例性实施例提供的一种埋点文档的应用示意图;
[0031]图6为本申请另一示例性实施例提供的一种埋点装置的结构示意图;
[0032]图7为本申请又一示例性实施例提供的计算设备的结构示意图。
[0033]具体实施方式
[0034]为使本申请的目的、技术方案和优点更加清楚,下面将结合本申请具体实施例及相应的附图对本申请技术方案进行清楚、完整地描述。显然,所描述的实施例仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
[0035]针对现有埋点方案中,在每次埋点时都需要人工选择工具函数,重新编写参数需求代码以及工具函数调用逻辑所导致的埋点效率较低的技术问题,本申请实施例提供一种解决方案,基本思路是:可在目标代码运行至用于触发对第一注解对应的目标事件进行埋点的预设函数的情况下,获取为预设函数添加的第一注解,从第一注解中提取为目标事件配置的至少一条参数描述信息作为目标参数需求信息。基于参数需求信息与工具函数之间的映射关系,为目标事件在埋点后所需使用的至少一个目标工具函数,以用于在目标事件埋点后采集目标事件对应的用户数据,将至少一个目标工具函数添加到目标代码中目标事件对应的埋点位置,以实现对目标事件的埋点。这样,可将目标参数需求信息的提取逻辑和目标工具函数的选取、调用逻辑,封装成通用埋点逻辑。在对目标事件埋点时,开发人员只需为预设函数配置第一注解,即可自动执行通用埋点逻辑:自动从第一注解中提取目标参数需求信息,无需人工编写参数需求代码;可基于参数需求信息与工具函数之间的映射关系自动选取目标工具函数,不再需要人工实时选择工具函数。并且,可将目标工具函数添加到目标代码中目标事件对应的埋点位置进行埋点,以在目标代码中将目标工具函数与目标事件进行关联,进而实现目标工具函数的调用逻辑的配置,而不再需要单独编写工具函数的调用逻辑。这大大减轻了开发人员的工作负担,缩短了为目标事件埋点所需耗费的时间,从而可有效提高埋点效率。
[0036]以下结合附图,详细说明本申请各实施例提供的技术方案。
[0037]图1为本申请一示例性实施例提供的一种埋点方法的流程示意图。该方法可由埋点装置执行,该埋点装置可实现为软件和/或硬件的结合,该埋点装置可集成在计算设备中。参考图1,该方法包括:
[0038]步骤100,在目标代码运行至预设函数的情况下,从目标代码中获取为预设函数添加的第一注解,预设函数为预先插入目标代码中且用于触发对第一注解对应的目标事件进行埋点的函数;
[0039]步骤101,从第一注解中提取为目标事件配置的至少一条参数描述信息作为目标参数需求信息,参数描述信息用于描述目标事件所需的待采集参数;
[0040]步骤102,基于参数需求信息与工具函数之间的映射关系,为目标事件确定在埋点后所需使用的至少一个目标工具函数,至少一个目标工具函数用于在目标事件埋点后采集目标事件对应的用户数据;
[0041]步骤103,将至少一个目标工具函数添加到目标代码中目标事件对应的埋点位置,以实现在目标代码中对目标事件的埋点。
[0042]本实施例中,埋点通常发生在需要记录和追踪用户数据的事件上,这些事件可以是在应用程序或网站中,用户与界面的各种交互操作或行为,主要包括行为事件和曝光事件两大类。其中,行为事件包括但不限于:用户点击按钮、在输入框中输入文本、滑动页面等;曝光事件包括但不限于:页面显示、页面元素的显示或隐藏、弹窗的显示等。
[0043]本实施例提供的一种埋点方法可应用于各种需要对用户数据进行追踪和分析的场景中。例如,可对电商应用程序中的“点击支付按钮”事件进行埋点,来对用户的购买行为进行追踪和分析,以优化商品推荐和促销活动;还可对新闻门户网站中的“页面显示”事件进行埋点,来对用户的浏览行为进行追踪和分析,以提高新闻推荐的精准性和个性化。当然,还可以应用在其他需要对用户数据进行追踪和分析的场景中,在此不再穷举。
[0044]可选地,在步骤100之前,开发人员可根据对目标事件的埋点需求,编写用于触发对第一注解对应的目标事件进行埋点的预设函数,并将预设函数插入源代码中,这里所说的源代码是与目标事件相关联的源代码,而目标事件可以是任意一种需要记录和追踪用户数据的事件。例如,若目标事件为点击APP中的注册按钮,则源代码为APP对应的源代码,可在APP对应的源代码中插入用于触发对“点击注册按钮”事件进行埋点的预设函数。
[0045]一种将预设函数插入源代码的可选实现方式中,可在源代码中创建预设函数,响应于针对预设函数的注解输入操作,获取为预设函数编写的第一注解,并在源代码中为预设函数添加第一注解。第一注解中可包括但不限于目标事件对应的埋点位置和目标事件名称等标识信息,可通过目标事件对应的埋点位置和目标事件名称等标识信息,为第一注解确定其所对应的目标事件。也即是,通过第一注解为插入至源代码中的预设函数关联了相应的目标事件。在源代码中为预设函数添加第一注解之后,可对源代码进行编译,以得到编译后的目标代码,后续运行的即是编译后所得到的目标代码。
[0046]在该实现方式中,在源代码中创建的预设函数通常是空白的,预设函数可用于承载第一注解,第一注解则用于反映针对目标事件的埋点需求。在源代码中为预设函数添加第一注解,可通过注解的形式在源代码中描述针对目标事件的埋点需求,使得后续可从第一注解中提取出目标参数需求信息,不再需要单独编写能够反映目标事件的埋点需求的参数需求代码,减少了开发人员在埋点过程中的工作负担,从而可提高埋点效率。当然,创建出的预设函数也可以不是空白的,例如,对已有埋点进行更新时,可在原有预设函数的基础上添加新的第一注解,此时在插入新的第一注解前所创建的预设函数中包含有旧的第一注解。
[0047]本实施例中,预设函数中可包含对目标事件进行埋点所需的至少一个参数,埋点所需的参数通常是根据具体的数据采集需求和数据分析目的确定出来的,这些参数可包括但不限于埋点信息、目标事件信息以及数据分析方式等。其中,埋点信息包括埋点文档名称、埋点类型、埋点目的、埋点名称和埋点版本等;目标事件信息包括但不限于目标事件名称、目标事件对应的埋点位置、目标事件类型、目标事件时间戳以及目标事件属性等。
[0048]下面对预设函数中可能包含的参数所表征的含义进行简要介绍。
[0049]埋点文档名称:用于表示生成的埋点文档的名称,如“购物-本地埋点”。
[0050]埋点类型:用于表征埋点对应的类型,如“本地埋点”、“动态下发埋点”等。
[0051]埋点目的:用于表征收集用户数据的目的与意义,如“分析用户购买行为”。
[0052]埋点名称:用于表示触发埋点的动作/行为的名称,如“点击购买”、“商品详情浏览”等。
[0053]埋点版本:用于表示埋点当前的版本,如“1.0.0”、“V2.0”等。
[0054]目标事件名称:用于表示在目标代码中定义的目标事件的名称,如“BuyClick”。
[0055]目标事件对应的埋点位置:用于表示目标事件在目标代码中所处的位置,如“0056行”。
[0056]目标事件类型:用于表示事件的具体类型,例如,“点击”、“展示”、“用户输入”等。
[0057]目标事件时间戳:用于表示用户触发埋点的时间,通常可精确到秒或毫秒级别。
[0058]目标事件属性:用于描述目标事件所需的待采集参数,如用户信息、用户的设备信息等;每个待采集参数可对应一条参数描述信息,参数描述信息中包括但不限于参数名、参数所对应的数据类型等。用户信息包括但不限于用户ID、用户点击次数、用户的浏览时间、用户的登录状态等;设备信息包括但不限于用户的操作系统、用户的浏览器类型、用户的屏幕分辨率等。
[0059]本实施例中,可采用Java注解来描述预设函数中的至少一个参数,Java注解不会改变目标代码原本的执行逻辑,但是可以为目标代码提供额外的信息。在使用Java注解描述预设函数中的至少一个参数的过程中,可对Java注解的生命周期进行定义,将Java注解所表示的参数的生命周期划分为三种类型:
[0060]1、源文件有效(SOURCE):注解只保留在源文件阶段,当Java源文件被编译成类文件后,这些注解失效;
[0061]2、在源代码的编译期间有效(CLASS):注解只被保留到类文件阶段,当JVM加载类文件到内存中后,这些注解失效即被遗弃;
[0062]3、在目标代码的运行期间有效(RUNTIMR):注解不仅被保存到类文件中,且在JVM加载类文件到内存之后,这些注解仍然有效。
[0063]这三种生命周期分别对应于Java源文件到类文件,再到内存中的字节码的过程,生命周期的长度关系为:SOURCE<CLASS<RUNTIM。
[0064]可选地,可将对目标代码进行解释说明的参数的生命周期配置为源文件有效。将对目标事件埋点所需的参数的生命周期配置为在目标代码的运行期间有效,例如,可将用于描述目标事件信息的参数的生命周期配置为在目标代码的运行期间有效,并将这些参数组合在一起,构成第一注解。将其他与埋点相关的参数配置为在源代码的编译期间有效,例如,可将用于描述埋点信息及数据分析方式的参数的生命周期配置为在源代码的编译期间有效,并将这些参数组合在一起,构成第二注解,关于第二注解的具体内容细节将在下文进行详述。
[0065]进一步地,可将第一注解划分为第一函数注解和第一参数注解。根据参数的使用频率,可将多个埋点都需要使用的参数定义为公共参数,如用户ID、用户的浏览时间等,将至少一个公共参数封装到第一函数注解中,使得后续在为其它事件定义预设函数时可直接引用第一函数注解,从而实现公共参数的复用。第一参数注解中可包含至少一个非公共参数,第一参数注解中所包含的参数可以是根据实际埋点需求个性化定义的,不同事件对应的预设函数中所包含的第一参数注解可不完全相同。
[0066]图2为本申请一示例性实施例提供的一种埋点方法的逻辑示意图。如图2所示,埋点装置可向目标代码发送监测信号,以对目标代码的运行进度进行实时监测,在监测到目标代码运行至预设函数的情况下,可从目标代码中获取为预设函数添加的第一注解。或者,目标代码可在运行到预设函数时,向埋点装置返回一确认信号,以使埋点装置响应于回馈信号,从目标代码中获取为预设函数添加的第一注解。其中,预设函数为预先插入目标代码中且用于触发对第一注解对应的目标事件进行埋点的函数,运行到预设函数即触发埋点装置获取第一注解。以使埋点装置基于第一注解确定至少一个目标工具函数,并将至少一个目标工具函数插入至目标代码中目标事件对应的埋点位置,实现对目标事件的埋点。
[0067]本实施例中,可采用多种实现方式从目标代码中获取为预设函数添加的第一注解。在一种可选实现方式中,可利用动态代理从目标代码中获取为预设函数添加的第一注解。动态代理是在目标代码运行期间为实现第一注解的获取而额外生成的代理对象,其可以在不修改原始类和接口的情况下,为对象提供额外的功能和行为。
[0068]在该实现方式中,可针对预设函数创建动态代理,利用动态代理为预设函数创建接口实现类,并调用接口实现类中的读函数,该读函数用于触发动态代理从目标代码中读取为预设函数添加的第一注解,其本身并不具有读取第一注解的功能。在接收到读函数对应的回调信息之后,可利用动态代理根据回调信息中包含的第一注解标识从目标代码中读取为预设函数添加的第一注解。其中,在创建接动态代理之前,可对预设函数进行合法性验证,并在验证通过的情况下,为该服务接口创建动态代理。
[0069]在利用动态代理读取为预设函数添加的第一注解时,可通过反射机制读取第一注解,反射是Java内部的一个功能,其允许在运行时对类进行操作,通过反射可以获取类内部的预设函数,并动态的调用为预设函数添加的第一注解。对动态代理而言,在需要读取第一注解时,可调用接口实现类中的读函数,若接收到读函数对应的回调信息,则可根据回调信息中包含的第一注解标识,利用反射机制从目标代码中读取为预设函数添加的第一注解;若未接收到读函数对应的回调信息,则表明读函数调用失败,无法执行第一注解的读取操作,可提示注解读取异常。
[0070]当然,也可以采用其他实现方式获取第一注解,例如,可不引入动态代理,而是由埋点装置内部的控制模块直接从目标代码中提取为预设函数添加的第一注解,本实施例对此不做限定。
[0071]继续参考图1,在步骤101中,可从第一注解中提取为目标事件配置的至少一条参数描述信息作为目标参数需求信息。参数描述信息用于描述目标事件所需的待采集参数,每个待采集参数对应一条参数描述信息,待采集参数可包括但不限于用户ID、用户点击次数、用户的操作系统、用户所采用的浏览器类型等,目标参数需求信息中可包含针对目标事件的一个或多个待采集参数各自对应的参数描述信息,参数描述信息中可包含待采集参数的至少一个属性信息,例如,参数名、参数的数据类型等。如前文所述,第一注解中还包含目标事件名称和目标事件对应的埋点位置等,也即是,第一注解主要用于描述目标事件的详细信息。
[0072]在该步骤中,可由埋点装置内部的控制模块直接从第一注解中提取为目标事件配置的至少一条参数描述信息作为目标参数需求信息,也可以采用前文所创建的动态代理来提取为目标事件配置的至少一条参数描述信息作为目标参数需求信息,或者采用其他的可行性方式实现参数描述信息的提取,在此不做穷举。
[0073]基于此,一种采用动态代理从第一注解中提取为目标事件配置的至少一条参数描述信息的可选实现方式中,可利用动态代理遍历读取到的第一注解,以确定为目标事件配置的至少一个待采集参数。继续利用动态代理,确定各待采集参数各自对应的注解类型,并按照各注解类型各自对应的提取规则,从第一注解中提取各待采集参数各自对应的参数描述信息作为目标参数需求信息。其中,注解类型可包括动态注解类型、静态注解类型及json注解类型等。
[0074]采用动态代理可实现埋点逻辑的标准化、规范化,在预设函数触发埋点后,可针对预设函数创建动态代理,并采用动态代理自动获取第一注解并从第一注解中提取为目标事件配置的至少一条参数描述信息,而不再需要为每次埋点单独编写参数采集逻辑,减轻了开发人员的工作负担,从而可有效提高埋点效率。
[0075]在该实现方式中,针对任一待采集参数,可按照各注解类型各自对应的提取规则,从第一注解中提取各待采集参数各自对应的参数描述信息:
[0076]若待采集参数的注解类型为动态注解类型,则从第一注解中提取该待采集参数对应的参数名和数据类型。若提取出的数据类型符合预设的数据类型要求,则将提取到的待采集参数对应的参数名和数据类型,作为该待采集参数的参数描述信息;若数据类型不符合预设的数据类型要求,则按照预设的数据类型要求,对提取到的数据类型进行类型转换,将该待采集参数对应的参数名和转换后的数据类型,作为该待采集参数的参数描述信息。
[0077]若待采集参数的注解类型为静态注解类型,则从第一注解中提取该待采集参数对应的参数名和数据类型,作为该待采集参数的参数描述信息。
[0078]若待采集参数的注解类型为json注解类型,则采用和动态注解类型相同的提取规则,具体的实现细节可参考前述动态注解类型对应的提取规则,为节省篇幅,在此不再赘述。
[0079]本实施例中,为每种注解类型下的待采集参数分别配置了相应的提取规则,按照各注解类型各自对应的提取规则从第一注解中提取参数描述信息,可有效避免因注解类型不同而导致提取结果不准确情况的发生,使得提取出的参数描述信息可以精准表征针对目标事件的埋点需求,进而保证了确定出的目标工具函数的准确性,从而有效提高了埋点的准确性。
[0080]在步骤102中,可基于参数需求信息与工具函数之间的映射关系,为目标事件确定在埋点后所需使用的至少一个目标工具函数,至少一个工具函数可用于在目标事件埋点后采集目标事件对应的用户数据,目标事件对应的用户数据中包括目标事件所需的各待采集参数各自对应的用户数据。图3为本申请一示例性实施例提供的一种确定至少一个目标工具函数的流程图,如图3所示,可基于参数需求信息与工具函数之间的映射关系,确定目标参数需求信息对应的目标工具函数;若可直接映射到一个工具函数,则将映射到的工具函数作为目标工具函数;若映射到多个工具函数,则从中选择一个作为目标工具函数,可随机从多个工具函数中任意选择一个作为目标工具函数,也可以预先为工具函数设置优先级,以从多个函数中选择优先级最高的一个作为目标工具函数。
[0081]继续参考图3,若基于目标参数需求信息无法直接映射到工具函数,则可将目标需求信息拆分成多个子参数需求信息,也即是将目标参数需求中所包含的至少一条参数描述信息划分为多个组合。继续基于参数需求信息与工具函数之间的映射关系,确定各子参数需求信息各自对应的工具函数,此时可参考前述为目标参数需求信息确定目标工具函数的步骤,为每个子参数需求信息确定出唯一的工具函数。将多个子参数需求信息各自对应的工具函数,均作为目标参数需求信息对应的目标工具函数,也即是,可为目标参数需求信息确定出多个目标工具函数。举例来说,目标参数需求信息中包含4个待采集参数对应的参数描述信息,记录目标参数需求信息为{a,b,c,d},目标参数需求信息{a,b,c,d}无法直接映射到目标工具函数。可将目标需求信息拆分成子参数需求信息{a,b}和{c,d},根据参数需求信息与工具函数之间的映射关系{参数需求信息{a,b}映射工具函数A,参数需求信息{c,d}映射工具函数B},可为目标事件确定出两个工具函数A和B,在目标事件埋点后,可采用工具函数A采集待采集参数a和b对应的用户数据,采用工具函数B采集待采集参数c和d对应的用户数据。
[0082]另外,可采用多种实现方式构建参数需求信息与工具函数之间的映射关系。例如,可由开发人员根据自身经验,自主构建出参数需求信息与工具函数之间的映射关系;也可以将历史数据中使用各工具函数时所对应的参数需求信息作为数据集,采用该数据集对神经网络模型进行训练,以得到包含参数需求信息与工具函数之间映射关系的映射模型。当然,还可以采用其他实现方式构建参数需求信息与工具函数之间的映射关系,在此不作限定。
[0083]值得一提的是,目标工具函数的确定过程也可以由动态代理执行,采用动态代理可统一为目标事件埋点选取工具函数的选取逻辑,不再需要为每个埋点重复编写工具函数的调用逻辑,可以更加方便、快捷地确定出埋点所需的工具函数,从而可进一步提高埋点效率。
[0084]在此基础上,可将至少一个目标工具函数添加到目标代码中目标事件对应的埋点位置,以实现在目标代码中对目标事件的埋点,从而完成埋点的部署。在实际应用中,开发人员可在目标代码中定义目标事件,目标事件的发生通常非常容易描述,仅需少量代码即可表述清楚,减轻了开发人员的工作负担。确定出至少一个目标工具函数后,可将至少一个目标工具函数添加到目标代码中目标事件对应的埋点位置,以将至少一个目标工具函数和目标代码中的目标事件关联在一起。
[0085]需要说明的是,在目标代码中,目标事件对应的埋点位置可以与目标事件所处的位置处于相同位置或不同位置,目标事件对应的埋点位置与目标事件相关联,只要保证在目标事件被触发时能够从目标事件对应的埋点位置成功调用到至少一个目标工具函数即可。在两个目标事件的埋点需求完全相同的情况下,两个目标事件对应的目标参数需求信息可能完全相同,因此,映射出完全相同的目标工具函数。此时,可将两个目标事件对应同一埋点位置,仅在该埋点位置插入目标工具函数,将这两个目标事件均关联至该目标工具函数上,以采用该目标工具函数对这两个目标事件进行埋点,减轻了配置工作负担,可提高埋点效率。也可以分别为每个目标事件配置单独的埋点位置,在两个埋点位置分别插入目标工具函数,将这两个目标事件分别关联至不同位置的目标工具函数上,使得两个目标事件的埋点调用互不干扰,从而保证埋点调用的流畅性。
[0086]据此,可将目标参数需求信息的提取逻辑和目标工具函数的选取、调用逻辑,封装成通用埋点逻辑。在对目标事件埋点时,开发人员只需为预设函数添加第一注解,即可利用动态代理自动从第一注解中提取目标参数需求信息,无需人工编写参数需求代码;还可基于参数需求信息与工具函数之间的映射关系自动选取目标工具函数,并将目标工具函数添加到目标代码中目标事件对应的埋点位置进行埋点,以在目标代码中将目标工具函数与目标事件进行关联,从而实现对目标事件的埋点。不再需要人工实时选择工具函数,也不再需要单独编写工具函数的调用逻辑,减轻了开发人员的工作负担,缩短了为目标事件埋点所需耗费的时间,从而可有效提高埋点效率。
[0087]在上述或下述实施例中,在实际部署埋点之前,可通过模拟用户行为或使用测试工具对埋点效果进行测试,以确保能准确地捕获和记录用户数据。在完成埋点的实际部署后,可调用目标事件上的埋点来捕获和记录触发目标事件的用户的行为数据。调用目标事件上的埋点可分为本地埋点调用和动态下发埋点调用两种情况,本地埋点调用指的是调用在本地配置的目标事件上的埋点,动态下发埋点调用则表示通过远程服务远程调用其他服务器上配置的目标事件上的埋点。采用动态下发埋点调用的方式,可避免重复配置相同的埋点,减少了埋点配置的工作量,从而有效提高埋点效率。
[0088]可选地,在一种本地埋点调用的实现方式中,可采用埋点工具对目标事件的状态进行实时监测,在监测到目标事件被用户触发的情况下,可调用目标事件所关联的至少一个目标工具函数,以使至少一个目标工具函数分别按照各自映射的参数需求信息确定待采集参数,并采集待采集参数对应的用户数据,基于用户数据生成针对目标事件的埋点日志。其中,若调用的目标工具函数只有一个,则该目标工具函数可按照目标参数需求信息采集待采集参数对应的用户数据,该目标工具函数采集到的用户数据即为目标事件对应的用户数据;若调用的目标工具函数为多个,则每个目标工具函数都对应一子参数需求信息,每个目标工具函数可按照各自对应的子参数需求信息采集待采集参数对应的用户数据,多个目标工具函数采集到的用户数据共同组成目标事件对应的用户数据。当然,还可以采用工具函数自行对目标事件的状态进行实时监测,在此不对监测目标事件状态的方式进行限定。
[0089]对目标事件而言,其可以被数以万计的用户触发,可预先为目标事件创建一空白的埋点日志并存储到指定位置。采集到用户数据后,即将采集到的用户数据写入指定位置存储的埋点日志中。当然,还可以在写入埋点日志之前,对采集到的用户数据进行数据整理、格式转换等操作,以使最后得到的埋点日志可以更加直观、准确的反映用户数据,方便利用埋点日志直接进行数据分析、数据决策等。
[0090]进一步地,还可采用多种实现方式对目标事件的埋点进行更新。一种可选的实现方式中,可响应于针对目标事件的埋点更新指令,展示埋点更新界面。获取埋点更新界面上发生的修改操作所对应的埋点更新信息,以得到更新后的第一注解,并基于更新后的第一注解更新目标代码。在更新后的目标代码运行到预设函数时,可重新执行对目标事件的埋点流程,以实现对目标事件埋点的更新。
[0091]在该实现方式中,埋点更新界面上发生的修改操作可以是开发人员执行的,也可以是埋点装置自动触发的。开发人员可根据目标事件的埋点更新需求向埋点装置发送埋点更新指令,以触发埋点装置向开发人员展示埋点更新界面,使得开发人员可在埋点更新界面上使用Java注解执行修改操作,例如,可以对待采集参数进行增加、调整以及删除等操作,以生成修改操作对应的埋点更新信息。或者,可在埋点装置中对目标事件的埋点配置定期更新的逻辑,以自动触发修改操作,并生成修改操作对应的埋点更新信息。
[0092]据此,采用注解的形式对目标事件的埋点进行更新,可解决参数需求代码不易修改的问题,降低了维护难度,方便后期维护,从而进一步有效增强了埋点调用的可扩展性。
[0093]在上述或下述实施例中,可采用多种实现方式为目标事件生成埋点文档。
[0094]图4为本申请一示例性实施例提供的一种生成埋点文档的方法流程图,参考图4,在一种为目标事件生成埋点文档的可选实现方式中,可包括以下步骤:
[0095]步骤400,在源代码编译至预设函数的情况下,调用预设的技术分析工具;
[0096]步骤401,利用技术分析工具扫描预设函数,以获取为预设函数添加的类注解和第二注解;
[0097]步骤402,从类注解中提取埋点文档名称,以根据埋点文档名称获取类注解对应的埋点文档;
[0098]步骤403,将第二注解写入类注解对应的埋点文档,以生成目标事件对应的埋点文档,第二注解中包含至少一条参数信息,参数信息用于描述目标事件所需的待记录参数。
[0099]在步骤400和步骤401中,可对插入预设函数后的源代码进行编译,当编译到预设函数时调用预设的技术分析工具,并利用技术分析工具对预设函数进行扫描,以从预设函数中获取到类注解和第二注解。技术分析工具是一种可以在编译时对注解进行扫描和处理的工具,本实施例中可预先配置注解处理工具(Annotation Processing Tool,APT)作为技术分析工具,并初始化APT环境,也可以采用Lombok、Dagger等其它技术分析工具,Lombok是一个Java库,Lombok的注解处理器可在编译时可扫描和处理注解,Dagger是一个依赖注入框架,Dagger的注解处理器可在编译时扫描和处理注解,本实施例在此不做限定。
[0100]当然,也可以在开始编译源代码时即调用预设的技术分析工具,以利用技术分析工具对整个源代码进行扫描,从源代码中获取到为预设函数添加的类注解和第二注解。这种情况下,若源代码中存在多个预设函数,可通过技术分析工具的扫描得到各个预设函数各自对应的类注解和第二注解。
[0101]本实施例中,类注解与第二注解中包含了需要在埋点文档中进行记录的参数,基于类注解和第二注解生成埋点文档,可方便开发人员通过埋点文档对埋点的相关信息进行反向查询。类注解主要用于对埋点进行宏观描述,类注解可包括但不限于埋点文档名称、埋点类型等;第二注解主要用于描述在应用或网站中设置的埋点的详细信息,方便开发人员通过第二注解所包含的内容了解埋点的目的、版本等信息,第二注解可包括但不限于埋点名称、埋点目的、埋点版本以及数据分析方式等信息。
[0102]同样地,也可以将第二注解划分为第二函数注解和第二参数注解。根据参数的使用频率,将多个埋点都需要记录的参数定义为公共参数,如埋点版本号、埋点目的等,将至少一个公共参数封装到第二函数注解中,使得后续在为其它事件配置埋点文档时可直接引用第二函数注解,从而实现公共参数的复用。第二参数注解中包含至少一个非公共参数,可根据埋点文档的记录需求个性化定义第二参数注解。
[0103]在步骤402中,可从类注解中提取埋点文档名称,以根据埋点文档名称获取类注解对应的埋点文档。需要说明的是,每个类注解下可以对应多个第二注解,不同第二注解对应的预设函数不同,每个预设函数关联不同的事件,这使得多个事件对应的埋点文档可以是同一个类注解对应的埋点文档。因此,在获取类注解对应的埋点文档时,可先基于类注解中的埋点文档名称,判断埋点文档库中是否已存在类注解对应的埋点文档。若存在,则可直接从埋点文档库中拉取类注解对应的埋点文档,埋点文档库中存储有多个类注解各自对应的埋点文档;若不存在,则可创建一空白的埋点文档,作为类注解对应的埋点文档。
[0104]基于此,可将第二注解写入类注解信息对应的埋点文档,以生成目标事件对应的埋点文档,方便开发人员通过埋点文档正确地埋点、了解埋点情况、准确分析埋点数据以及反向查询埋点数据等。并且,通过明确的文档指导,可以提高团队的协作效率,减少因信息不一致而导致的误解和错误。
[0105]可选地,在将第二注解写入类注解信息对应的埋点文档时,可从第二注解中提取目标事件所需的各待记录参数各自对应的参数信息,参数信息中可包含待记录参数的参数名以及参数名对应的参数值等。在类注解对应的埋点文档中,建立参数名和该参数名对应的参数值之间的关联关系,以实现第二注解的写入。图5为本申请一示例性实施例提供的一种埋点文档的应用示意图。如图5所示,若类注解对应的埋点文档是电子表格(Spreadsheet),则可在电子表格中各列的首个单元格中分别部署各待记录参数各自对应的参数名,如图5中的参数名包括埋点名称、预设函数名称、埋点版本以及埋点详细信息地址等;再将参数名对应的参数值写入该参数名下方的单元格中,例如,将参数值“1.0.0”写入其对应的参数名“埋点版本”下方的单元格中。其中,埋点详细信息地址这一参数是可以自由选择的,也可以选择直接将全部埋点详细信息平铺展示在埋点文档中。当然,埋点文档也可通过文本(Text)或文档(Document)等格式进行呈现,在此不对埋点文档的文件格式进行限定。
[0106]在实际应用中,类注解对应的埋点文档中可包含多个目标事件的第二注解,还可将多个类注解对应的埋点文档合并在一起。如图5所示,该电子表格中包含三个类注解对应的埋点文档,分别是“购物-本地埋点”、“购物-本地埋点”和“购物-本地埋点”,“购物-本地埋点”这个类注解对应的埋点文档中包含三个目标事件。
[0107]据此,可在为预设函数添加第一注解的同时,为预设函数添加类注解和第二注解,并将类注解和第二注解的生命周期配置为在源代码的编译期间有效,使得类注解和第二注解不会影响运行期间对目标事件的埋点。而目标代码运行前需要执行编译,在编译期间可基于类注解和第二注解自动生成埋点文档,方便统计埋点和反向查询埋点信息,无需额外执行埋点文档的生成工作,提高了埋点文档的生成效率。
[0108]需要说明的是,上述实施例所提供方法的各步骤的执行主体均可以是同一设备,或者,该方法也由不同设备作为执行主体。比如,步骤100至步骤103的执行主体可以为设备A;又比如,步骤100和步骤101的执行主体可以为设备A,步骤102的执行主体可以为设备B;等等。
[0109]另外,在上述实施例及附图中的描述的一些流程中,包含了按照特定顺序出现的多个操作,但是应该清楚了解,这些操作可以不按照其在本文中出现的顺序来执行或并行执行,操作的序号如100、101等,仅仅是用于区分开各个不同的操作,序号本身不代表任何的执行顺序。另外,这些流程可以包括更多或更少的操作,并且这些操作可以按顺序执行或并行执行。需要说明的是,本文中的“第一”、“第二”等描述,是用于区分不同的消息、设备、模块等,不代表先后顺序,也不限定“第一”和“第二”是不同的类型。
[0110]图6为本申请另一示例性实施例提供的一种埋点装置的结构示意图。埋点装置可实现为软件和/或硬件的结合,埋点装置可与目标事件所在的应用程序或网站等进行交互。如图6所示,埋点装置600可包括监测模块601、控制模块602和埋点模块603。其中:
[0111]监测模块601,用于监测目标代码的运行进度,当监测到目标代码运行至预设函数时,向控制模块602发送注解读取指令;
[0112]控制模块602,用于接收监测模块601发送的注解读取指令,从目标代码中获取为预设函数添加的第一注解,预设函数为预先插入目标代码中且用于触发对第一注解对应的目标事件进行埋点的函数;从第一注解中提取为目标事件配置的至少一条参数描述信息作为目标参数需求信息,将目标参数需求信息发送至埋点模块,其中,参数描述信息用于描述目标事件所需的待采集参数;
[0113]埋点模块603,用于接收控制模块602发送的目标参数需求信息,基于参数需求信息与工具函数之间的映射关系,为目标事件确定在埋点后所需使用的至少一个目标工具函数,将至少一个目标工具函数添加到目标代码中目标事件对应的埋点位置,以实现在目标代码中对目标事件的埋点。其中,至少一个目标工具函数用于在目标事件埋点后采集目标事件对应的用户数据。
[0114]在一可选实施例中,埋点装置还可包括代理模块604;
[0115]代理模块604,用于为预设函数创建接口实现类,并调用接口实现类中的读函数;在接收到读函数对应的回调信息之后,根据回调信息中包含的第一注解标识从目标代码中读取为预设函数添加的第一注解,并将第一注解发送至控制模块602。其中,读函数可用于触发代理模块604从目标代码中读取为预设函数添加的第一注解。
[0116]控制模块602,还用于接收代理模块604发送的第一注解,以实现从目标代码中获取为预设函数添加的第一注解。
[0117]在一可选实施例中,代理模块604,还用于接收控制模块602发送的提取指令;响应于提取指令,遍历读取到的第一注解,以确定为目标事件配置的至少一个待采集参数;确定各待采集参数各自对应的注解类型,以按照各注解类型各自对应的提取规则,从第一注解中提取各待采集参数各自对应的参数描述信息作为目标参数需求信息;将目标参数需求信息发送至控制模块602;
[0118]控制模块602,还用于向代理模块604发送提取指令,以供代理模块604基于提取指令,从第一注解中提取至少一条参数描述信息作为目标参数需求信息;接收代理模块604发送的目标参数需求信息。
[0119]值得说明的是,上述关于埋点装置各实施例中的技术细节,可参考前述的埋点方法各实施例中对埋点装置的动作的相关描述,为节省篇幅,在此不再赘述,但这不应造成本申请保护范围的损失。前述实施例中的埋点装置可以实现为软件或实现为软件和硬件的组合,该埋点装置可集成设置在计算设备中。
[0120]图7为本申请又一示例性实施例提供的一种计算设备的结构示意图。如图7所示,该计算设备包括:存储器70、处理器71以及通信组件72。
[0121]处理器71,与存储器70和通信组件72耦合,用于执行存储器70中的计算机程序,以用于:
[0122]在通信组件72监测到目标代码运行至预设函数的情况下,从目标代码中获取为预设函数添加的第一注解,预设函数为预先插入目标代码中且用于触发对第一注解对应的目标事件进行埋点的函数;
[0123]从第一注解中提取为目标事件配置的至少一条参数描述信息作为目标参数需求信息,参数描述信息用于描述目标事件所需的待采集参数;
[0124]基于参数需求信息与工具函数之间的映射关系,为目标事件确定在埋点后所需使用的至少一个目标工具函数,至少一个目标工具函数用于在目标事件埋点后采集目标事件对应的用户数据;
[0125]将至少一个目标工具函数添加到目标代码中目标事件对应的埋点位置,以实现在目标代码中对目标事件的埋点。
[0126]在一可选实施例中,从目标代码中获取为预设函数添加的注解的过程中,处理器71还用于:
[0127]针对预设函数创建动态代理;
[0128]利用动态代理为预设函数创建接口实现类,并调用接口实现类中的读函数;
[0129]在接收到读函数对应的回调信息之后,利用动态代理根据回调信息中包含的第一注解标识从目标代码中读取为预设函数添加的第一注解。
[0130]在一可选实施例中,处理器71在从第一注解中提取为目标事件配置的至少一条参数描述信息作为目标参数需求信息的过程中,还用于:
[0131]利用动态代理遍历读取到的第一注解,以确定为目标事件配置的至少一个待采集参数;
[0132]利用动态代理,确定各待采集参数各自对应的注解类型;
[0133]利用动态代理,按照各注解类型各自对应的提取规则,从第一注解中提取各待采集参数各自对应的参数描述信息,作为目标参数需求信息。
[0134]在一可选实施例中,在按照各注解类型各自对应的提取规则,从第一注解中提取各待采集参数各自对应的参数描述信息的过程中,处理器71还用于:
[0135]针对任一待采集参数,若待采集参数的注解类型为动态注解类型,则从第一注解中提取待采集参数对应的参数名和数据类型;若数据类型符合预设数据类型要求,则将提取到的待采集参数对应的参数名和数据类型,作为待采集参数的参数描述信息;若数据类型不符合预设数据类型要求,则按照预设的数据类型要求,对提取到的待采集参数对应的数据类型进行类型转换;将待采集参数对应的参数名和转换后的数据类型,作为待采集参数的参数描述信息;
[0136]针对任一待采集参数,若待采集参数的注解类型为静态注解类型,则从第一注解中提取待采集参数对应的参数名和数据类型,作为待采集参数的参数描述信息。
[0137]在一可选实施例中,在运行目标代码之前,处理器71还用于:
[0138]在源代码中创建预设函数;
[0139]响应于针对预设函数的注解输入操作,获取为预设函数编写的第一注解,第一注解中包含目标事件名称和目标事件对应的埋点位置,目标事件的埋点位置和目标事件名称用于为第一注解确定其所对应的目标事件;
[0140]在源代码中,为预设函数添加第一注解;
[0141]对源代码进行编译,以得到目标代码。
[0142]在一可选实施例中,在对源代码进行编译的过程中,处理器71还用于:
[0143]在源代码编译至预设函数的情况下,调用预设的技术分析工具;
[0144]利用技术分析工具扫描预设函数,以获取为预设函数添加的类注解和第二注解;
[0145]从类注解中提取埋点文档名称,以根据埋点文档名称获取类注解对应的埋点文档;
[0146]将第二注解写入类注解对应的埋点文档,以生成目标事件对应的埋点文档,第二注解中包含至少一条参数信息,参数信息用于描述目标事件所需的待记录参数。
[0147]在一可选实施例中,在根据埋点文档名称,获取类注解对应的埋点文档的过程中,处理器71还用于:
[0148]基于类注解中的埋点文档名称,判断埋点文档库中是否已存在类注解对应的埋点文档;
[0149]若存在,则从埋点文档库中拉取类注解对应的埋点文档,埋点文档库中存储有多个类注解各自对应的埋点文档;
[0150]若不存在,则创建一空白的埋点文档,作为类注解对应的埋点文档。
[0151]在一可选实施例中,在将第二注解写入类注解对应的埋点的过程中文档,处理器71还用于:
[0152]从第二注解中提取目标事件所需的各待记录参数各自对应的参数信息,参数信息中包含待记录参数的参数名以及参数名对应的参数值;
[0153]在类注解对应的埋点文档中,建立参数名和参数名对应的参数值之间的关联关系。
[0154]在一可选实施例中,第一注解的生命周期为在目标代码的运行期间有效,类注解和第二注解的生命周期为在源代码的编译期间有效
[0155]在一可选实施例中,处理器71还用于:
[0156]响应于针对目标事件的埋点更新指令,展示埋点更新界面;
[0157]获取埋点更新界面上发生的修改操作所对应的埋点更新信息,以得到更新后的第一注解;
[0158]基于更新后的第一注解,更新目标代码。
[0159]在一可选实施例中,在对目标事件进行埋点后,处理器71还用于:
[0160]在目标事件被用户触发的情况下,调用至少一个目标工具函数,以使至少一个目标工具函数分别按照各自映射的参数需求信息确定待采集参数,并采集待采集参数对应的用户数据;
[0161]基于用户数据,生成针对目标事件的埋点日志。
[0162]进一步,如图7所示,该计算设备还包括:显示器73和电源组件74等其它组件。图7中仅示意性给出部分组件,并不意味着计算设备只包括图7所示组件。
[0163]值得说明的是,上述关于计算设备各实施例中的技术细节,可参考前述的埋点方法各实施例中对计算设备的动作的相关描述,为节省篇幅,在此不再赘述,但这不应造成本申请保护范围的损失。
[0164]相应地,本申请实施例还提供一种存储有计算机程序的计算机可读存储介质,计算机程序被执行时能够实现上述方法实施例中可由计算设备执行的各步骤。
[0165]本申请实施例还提供一种计算机程序产品,包括计算机程序。当计算机程序被处理器执行时可实现上述埋点方法中的步骤。需要说明的是,该计算机程序的技术方案与上述的埋点方法的技术方案属于同一构思,计算机程序的技术方案未详细描述的细节内容,均可以参见上述埋点方法的技术方案的描述。
[0166]上述图7中的存储器,用于存储计算机程序,并可被配置为存储其它各种数据以支持在计算平台上的操作。这些数据的示例包括用于在计算平台上操作的任何应用程序或方法的指令,联系人数据,电话簿数据,消息,图片,视频等。存储器可以由任何类型的易失性或非易失性存储设备或者它们的组合实现,如静态随机存取存储器(SRAM),电可擦除可编程只读存储器(EEPROM),可擦除可编程只读存储器(EPROM),可编程只读存储器(PROM),只读存储器(ROM),磁存储器,快闪存储器,磁盘或光盘。
[0167]上述图7中的通信组件被配置为便于通信组件所在设备和其他设备之间有线或无线方式的通信。通信组件所在设备可以接入基于通信标准的无线网络,如WiFi,2G、3G、4G/LTE、5G等移动通信网络,或它们的组合。在一个示例性实施例中,通信组件经由广播信道接收来自外部广播管理系统的广播信号或广播相关信息。在一个示例性实施例中,所述通信组件还包括近场通信(NFC)模块,以促进短程通信。例如,在NFC模块可基于射频识别(RFID)技术,红外数据协会(IrDA)技术,超宽带(UWB)技术,蓝牙(BT)技术和其他技术来实现。
[0168]上述图7中的显示器包括屏幕,其屏幕可以包括液晶显示器(LCD)和触摸面板(TP)。如果屏幕包括触摸面板,屏幕可以被实现为触摸屏,以接收来自用户的输入信号。触摸面板包括一个或多个触摸传感器以感测触摸、滑动和触摸面板上的手势。所述触摸传感器可以不仅感测触摸或滑动动作的边界,而且还检测与所述触摸或滑动操作相关的持续时间和压力。
[0169]上述图7中的电源组件,为电源组件所在设备的各种组件提供电力。电源组件可以包括电源管理系统,一个或多个电源,及其他与为电源组件所在设备生成、管理和分配电力相关联的组件。
[0170]本领域内的技术人员应明白,本申请的实施例可提供为方法、系统、或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
[0171]本申请是参照根据本申请实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
[0172]这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
[0173]这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
[0174]在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
[0175]内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
[0176]计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
[0177]还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、商品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、商品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、商品或者设备中还存在另外的相同要素。
[0178]以上所述仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。