插件加载方法及装置与流程

文档序号:12270985阅读:219来源:国知局
插件加载方法及装置与流程

本发明涉及计算机技术领域,特别是一种插件加载方法及装置。



背景技术:

IBinder是远程对象的基本接口,是为高性能而设计的轻量级远程调用机制的核心部分,Android的远程调用(即跨进程调用)就是通过IBinder实现的。但它不仅用于远程调用,也可以用于进程内调用。这个接口定义了与远程对象交互的协议。

IBinder的主要API(Application Program Interface,应用程序接口)是transact(),与它对应另一方法是Binder.onTransact()。第一个方法用于本端向远端的IBinder对象发送发出调用,第二个方法用于本端的远程对象能够响应接收到的调用。IBinder的API都是同步执行的,比如transact()直到对方的Binder.onTransact()方法调用完成后才返回。调用发生在进程内时无疑是这样的,而在进程间时,在IPC的帮助下,也是同样的效果。

相关技术中,可以采用Service的方式来获取IBinder对象,其优点是可以充分利用Service和IBinder的特性,但缺点也显而易见:

1)此方法是异步操作,每次bindService完成后,必须等待onServiceConnection回调后才能做下一步,这就需要在回调时记住上次操作的内容等,开发起来十分繁琐,且容易出错;

2)Service坑有限,无论是原来手机卫士的方案,还是DroidPlugin,要使用插件Service就需要申请多个“坑位”,一旦坑位不足,则会出现崩溃、找错Service等严重问题;

3)手机卫士的功能场景较多,这种插件间通信的方式是经常用到的,显然开发越轻量,效率越高,但单纯只用Service方案的话,还无法满足这一点。

在其它相关技术中,可以采用Socket通信(或类似形式)来“模拟”同步过程,具体做法是建立两个Socket,一个负责发送消息,一个负责接收消息。其中在发送消息方,在发出消息后开始读取缓存,以此进入阻塞状态,接收方收到消息后再发送给发送方,此时阻塞态消失,读取消息。此方案的优点是可做到同步进行,且传输媒介较为灵活(毕竟全是二进制)。然而,其缺点比单纯用Service还要明显:

(1)需要建立两个Socket进行通信,操作极其繁琐;

(2)一旦接收方进程意外终止,作为发送方无法立即知道情况,只能等待超时结束后才能继续,但问题是,超时既有可能是进程被退出,也有可能是出错;

(3)信道采用二进制,编写起来非常不直观;

(4)Socket通信在效率上不及IBinder;

(5)Socket通信存在一定的安全隐患。

综上所述,发明人发现亟待提供一种快速、同步地获取插件的IBinder对象的方案。



技术实现要素:

鉴于上述问题,提出了本发明以便提供一种克服上述问题或者至少部分地解决上述问题的插件加载方法及相应的装置。

依据本发明的一方面,提供了一种插件加载方法,包括:

当宿主程序接收到加载插件的请求时,调用插件加载方法对目标插件进行加载;

在加载目标插件的过程中,创建目标插件的入口类的对象;

利用所述入口类的对象,调用所述入口类中的指定方法缓存目标插件的接口的对象。

可选地,目标插件的接口的对象用于获取IBinder对象,所述方法还包括:

当外部调用方需要获取目标插件的IBinder对象时,调用预先定义的预定义类中的指定方法;

利用所述预定义类中的指定方法,从所述入口类中的指定方法中获取目标插件的接口的对象;

调用目标插件的接口的对象中的指定方法获取IBinder对象。

可选地,在调用目标插件的接口的对象中的指定方法获取IBinder对象之后,所述方法还包括:

利用获取的IBinder对象进行与所述目标插件进行通信。

可选地,所述目标插件的入口类为Entry类。

可选地,所述目标插件的接口为IPlugin接口,所述IPlugin接口的对象为mPlugin对象。

可选地,所述方法还包括:

利用所述入口类的对象,反射获取所述入口类中的指定方法。

可选地,当外部调用方需要获取目标插件的IBinder对象时,调用预先定义的预定义类中的指定方法,包括:

当外部调用方需要获取目标插件的IBinder对象时,判断所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程是否为同一进程;

若是,则直接调用预先定义的预定义类中的指定方法。

可选地,所述方法还包括:

若所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程不为同一进程,则通过所述目标进程中的Provider获取宿主程序的接口的对象;

由宿主程序的接口的对象中的指定方法,调用预先定义的预定义类中的指定方法。

可选地,所述目标进程为常驻进程。

可选地,所述宿主程序的接口为IpluginHost接口。

可选地,调用目标插件的接口的对象中的指定方法获取IBinder对象,包括:

调用目标插件的接口的对象中的指定方法;

根据module名字返回对应的IBinder对象。

可选地,当宿主程序接收到加载插件的指令时,调用插件加载方法对目标插件进行加载,包括:

将插件加载事件拆分为独立的至少一个加载阶段,其中,各个加载阶段对应不同的插件内容;

当宿主程序接收到加载插件的指令时,确定所述请求对应的目标加载阶段;

加载所述目标加载阶段对应的插件内容。

可选地,所述至少一个加载阶段包括下列至少之一:

插件信息的获取、插件资源的加载、插件代码的加载。

依据本发明的另一方面,还提供了一种插件加载装置,包括:

加载模块,适于当宿主程序接收到加载插件的指令时,调用插件加载方法对目标插件进行加载;

创建模块,适于在加载目标插件的过程中,创建目标插件的入口类的对象;

缓存模块,适于利用所述入口类的对象,调用所述入口类中的指定方法缓存目标插件的接口的对象。

可选地,目标插件的接口的对象用于获取IBinder对象,所述装置还包括:

调用模块,适于当外部调用方需要获取目标插件的IBinder对象时,调用预先定义的预定义类中的指定方法;

第一获取模块,适于利用所述预定义类中的指定方法,从所述入口类中的指定方法中获取目标插件的接口的对象;

第二获取模块,适于调用目标插件的接口的对象中的指定方法获取IBinder对象。

可选地,所述装置还包括:

通信模块,适于在所述第二获取模块调用目标插件的接口的对象中的指定方法获取IBinder对象之后,利用获取的IBinder对象进行与所述目标插件进行通信。

可选地,所述目标插件的入口类为Entry类。

可选地,所述目标插件的接口为IPlugin接口,所述IPlugin接口的对象为mPlugin对象。

可选地,所述装置还包括:

第三获取模块,适于利用所述入口类的对象,反射获取所述入口类中的指定方法。

可选地,所述调用模块还适于:

当外部调用方需要获取目标插件的IBinder对象时,判断所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程是否为同一进程;

若是,则直接调用预先定义的预定义类中的指定方法。

可选地,所述调用模块还适于:

若所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程不为同一进程,则通过所述目标进程中的Provider获取宿主程序的接口的对象;

由宿主程序的接口的对象中的指定方法,调用预先定义的预定义类中的指定方法。

可选地,所述目标进程为常驻进程。

可选地,所述宿主程序的接口为IpluginHost接口。

可选地,所述第二获取模块还适于:

调用目标插件的接口的对象中的指定方法;

根据module名字返回对应的IBinder对象。

可选地,所述加载模块还适于:

将插件加载事件拆分为独立的至少一个加载阶段,其中,各个加载阶段对应不同的插件内容;

当宿主程序接收到加载插件的指令时,确定所述请求对应的目标加载阶段;

加载所述目标加载阶段对应的插件内容。

可选地,所述至少一个加载阶段包括下列至少之一:

插件信息的获取、插件资源的加载、插件代码的加载。

本发明实施例提供的技术方案,当宿主程序接收到加载插件的请求时,调用插件加载方法对目标插件进行加载,在加载目标插件的过程中可以创建目标插件的入口类的对象,并利用入口类的对象,调用入口类中的指定方法缓存目标插件的接口的对象。由于该目标插件的接口的对象能够用于获取IBinder对象,因而当外部调用方需要获取目标插件的IBinder对象时,可以直接获取缓存的目标插件的接口的对象,并利用该目标插件的接口的对象来获取IBinder对象,进而可以利用获取的IBinder对象与目标插件进行通信。由此可见,本发明实施例能够充分利用Android系统的逻辑来实现在插件中快速、同步地获取IBinder对象,实现进程内或进程间的通信。

上述说明仅是本发明技术方案的概述,为了能够更清楚了解本发明的技术手段,而可依照说明书的内容予以实施,并且为了让本发明的上述和其它目的、特征和优点能够更明显易懂,以下特举本发明的具体实施方式。

根据下文结合附图对本发明具体实施例的详细描述,本领域技术人员将会更加明了本发明的上述以及其他目的、优点和特征。

附图说明

通过阅读下文优选实施方式的详细描述,各种其他的优点和益处对于本领域普通技术人员将变得清楚明了。附图仅用于示出优选实施方式的目的,而并不认为是对本发明的限制。而且在整个附图中,用相同的参考符号表示相同的部件。在附图中:

图1示出了根据本发明一实施例的插件加载方法的流程图;

图2示出了根据本发明一个实施例的插件加载装置的结构示意图;以及

图3示出了根据本发明另一个实施例的插件加载装置的结构示意图。

具体实施方式

下面将参照附图更详细地描述本公开的示例性实施例。虽然附图中显示了本公开的示例性实施例,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施例所限制。相反,提供这些实施例是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。

为解决上述技术问题,本发明实施例提供了一种插件加载方法。图1示出了根据本发明一实施例的插件加载方法的流程图。如图1所示,该方法至少包括以下步骤S102至步骤S106。

步骤S102,当宿主程序接收到加载插件的请求时,调用插件加载方法对目标插件进行加载。

步骤S104,在加载目标插件的过程中,创建目标插件的入口类的对象。

步骤S106,利用入口类的对象,调用入口类中的指定方法缓存目标插件的接口的对象。

本发明实施例提供的技术方案,当宿主程序接收到加载插件的请求时,调用插件加载方法对目标插件进行加载,在加载目标插件的过程中可以创建目标插件的入口类的对象,并利用入口类的对象,调用入口类中的指定方法缓存目标插件的接口的对象。由于该目标插件的接口的对象能够用于获取IBinder对象,因而当外部调用方需要获取目标插件的IBinder对象时,可以直接获取缓存的目标插件的接口的对象,并利用该目标插件的接口的对象来获取IBinder对象,进而可以利用获取的IBinder对象与目标插件进行通信。由此可见,本发明实施例能够充分利用Android系统的逻辑来实现在插件中快速、同步地获取IBinder对象,实现进程内或进程间的通信。

上文步骤S102中当宿主程序接收到加载插件的请求时,调用插件加载方法对目标插件进行加载,本发明实施例提供了一种可选的方案,即,将插件加载事件拆分为独立的至少一个加载阶段,其中,各个加载阶段对应不同的插件内容;当宿主程序接收到加载插件的指令时,确定请求对应的目标加载阶段;进而加载目标加载阶段对应的插件内容。这里,至少一个加载阶段可以包括插件信息的获取(即Info)、插件资源的加载(即Res)、插件代码的加载(即Dex)。在实际应用中,Info是最小单元,若要加载Res,则必须先加载Info;若要加载Dex,则必须先依次加载Info和Res。举例来说,外界调用load进行插件加载,TYPE表示要加载到哪个阶段(Info、Res和Dex)。同时调用loadInfo先进行Info的加载。loadInfo成功且TYPE为Info,表示只为加载Info,返回;loadRes成功且TYPE为Res,表示只为加载Info和Res,返回;loadDex成功且TYPE为Dex,表示需全部加载,直接返回。

在本发明的可选实施例中,当目标插件的接口的对象用于获取IBinder对象时,则当外部调用方需要获取目标插件的IBinder对象时,调用预先定义的预定义类中的指定方法,进而利用预定义类中的指定方法,从入口类中的指定方法中获取目标插件的接口的对象,从而可以调用目标插件的接口的对象中的指定方法获取IBinder对象。

进一步地,在调用目标插件的接口的对象中的指定方法获取IBinder对象之后,可以利用获取的IBinder对象进行与目标插件进行通信,来实现相应的功能或任务。

上文提及的插件的入口类可以为Entry类。插件的入口还可以如Activity、Service、Provider、Receiver和Application这五大入口。然而,Entry是插件里最早被调用的,它类似于Android的Dalvik.main,是整个插件最早入口的地方,适合在其中做初始化、缓存接口等操作。

进一步地,调用Entry类中的指定方法create方法来缓存插件的接口的对象,该插件的接口最终交回宿主程序,由宿主程序进行调度,实现宿主程序和插件之间的联动。这里,插件的接口可以为IPlugin接口,IPlugin接口的对象可以为mPlugin对象。IPlugin接口中可以声明插件的宿主、名字、描述、作者、版本等信息,以及UI工具栏、菜单等资源,并且可以根据需要进行添加或者删减。

在上文步骤S104利用入口类的对象,调用入口类中的指定方法缓存目标插件的接口的对象之前,本发明实施例还可以利用入口类的对象,反射获取入口类中的指定方法。

进一步地,上文提及,当外部调用方需要获取目标插件的IBinder对象时,调用预先定义的预定义类中的指定方法,本发明实施例提供了一种可选的方案,在该方案中,当外部调用方需要获取目标插件的IBinder对象时,可以判断外部调用方所在当前进程与即将返回目标插件的IBinder对象的接收方所在目标进程是否为同一进程;若是,则直接调用预先定义的预定义类中的指定方法;反之,若否,则通过目标进程中的Provider获取宿主程序的接口的对象,进而由宿主程序的接口的对象中的指定方法,调用预先定义的预定义类中的指定方法。

例如,预先定义的预定义类为PluginFactory类,该类是针对插件的对外入口类,该类的指定方法为query,定义该query方法用于快速获取IBinder对象。在本发明的可选实施例中,目标进程可以为常驻进程。此外,宿主程序的接口可以为IPluginHost接口,在这里向插件提供必要的宿主函数或资源,如文件对象、数据库的连接对象等等。这样,每一个插件都可以通过Host参数来访问宿主程序的资源或者函数。

上文提及的调用目标插件的接口的对象中的指定方法获取IBinder对象,本发明实施例提供了一种可选的方案,即,调用目标插件的接口的对象中的指定方法,进而根据module名字返回对应的IBinder对象。

在本发明的可选实施例中,在步骤S102创建插件的入口类的对象之后,还可以定义入口类中的指定方法返回表示加载失败的指定值(如,null等)。从而,在利用预定义类中的指定方法,从入口类中的指定方法中获取目标插件的接口的对象时,若从入口类中的指定方法中未获取到目标插件的接口的对象,并返回该指定值,则确定插件加载失败。

在一具体实施例中,Main Client为“宿主程序”部分,Plugin为“插件内部”部分,而Android System则为“系统API”,这里API是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的API而使操作系统去执行应用程序的命令或动作。在Main Client中定义PluginFactory、PluginLoader类,在Plugin中修改Entry类,下面将详细介绍获取插件的IBinder对象的过程。

首先是PluginFactory类。该类是唯一针对插件的对外入口类。这里因为只用到了query,故只列出此方法:

query:快速获取IBinder。寻找目标进程、寻找对应插件并加载等都在此方法中完成。具体用法和流程在后面有叙述。

其次是PluginLoader类。该类主要负责插件的加载部分:

load:加载一个插件。

query:被PluginFactory调用,一旦找到进程和插件,则此方法将直接调用先前已缓存好的IPlugin.query方法来使用。

然后是Entry类。该类是所有插件的入口类,仅有一个方法:

create:插件的入口。其返回值恰是本发明所用到的IPlugin对象。若返回null,则表示插件加载失败。

同时,一些插件初始化的流程也可在此方法中体现。

IPlugin接口是核心类之一,它是获取IBinder对象的入口,存在于插件内。

query:作为插件方,需实现此方法,并根据module名字返回对应的IBinder对象,供外界使用。

下面将从安装IBinder和使用IBinder两方面来详细介绍本发明的获取插件的IBinder对象的方法的实现过程。

首先,安装IBinder。每次加载插件时,本发明实施例都会尝试去缓存IPlugin类,而此类正是作为IBinder的获取类而存在的,下面将描述这种过程。

采用PluginLoader.load方法加载插件,在加载插件的过程中,需要创建插件的入口类(即Entry类)的对象,该对象和方法均需要通过反射来创建和调用,具体包括以下两个步骤101和102:

101:反射获取Entry.create方法的描述;

102:调用此方法描述,缓存mPlugin对象。

具体代码如下:

在本发明实施例中,为了方便起见,规定所有的插件入口类的全名遵循如下的规则:“com.qihoo360.plugin.”+插件名+“.Entry”。如摇一摇插件的入口类全名为:com.qihoo360.plugin.shakeoff.Entry。当然,也可以通过AndroidManifest.xml中的Meta-data来自定义Entry类的位置。

此外,在手机卫士产品中,将IPlugin变成AIDL(Android Interface Definition Language,Android接口定义语言)类,这样可以充分利用AIDL的一些特性。至此,IPlugin对象就缓存完成,并随时备用了。

其次,使用IBinder。在介绍之前,先定义一些术语:

调用方:指需要使用IBinder的一端,主要是调用PluginFactory.query的一端;

接收方:指返回IBinder的一端,主要是IPlugin.query端处理的一端;

目标进程:指接收方所在进程。接收方可以和调用方为一个进程,也可以跨进程去调用。

当外部插件需要使用IBinder时,需要经过几个步骤201至205:

201:首先判断目标进程是否为当前进程,换言之,调用方和接收方是否要求在一个进程中,若是,则继续执行202;反之,若否,则继续执行203。

202:获取IBinder对象。

203:判断目标进程是否为常驻进程。若是,则需要跨进程去调用常驻进程里的Query方法。

204:在常驻进程里有一个Provider,获取IPluginHost(也是IBinder)对象,然后再做下一步操作。

205:利用AIDL调用IPluginHost.queryPluginBinder方法,其仍调用的是PluginFactory,只不过这次传递的目标进程是“当前的”。

具体代码如下:

以下将重点说明步骤202、204和205。

实际上,本发明实施例提供了“单进程”和“跨进程”两种方案。如果是“单进程”方案的话,只需要202步骤即可,其它步骤均可省略。而“跨进程”方案则需要考虑很多种情况,故仍需上述所有步骤。

在步骤202中,首先定义PluginFactory.query方法。该方法用来获取或加载插件,并调用其IPlugin提供的接口,步骤如下301至307:

301-302:尝试获取或者加载插件Dex,返回符合条件的PluginLoader对象;

303-305:通过PluginLoader对象中的query()方法,来尝试从Entry中拿到IPlugin的对象,来调用其query方法,以获取IBinder对象。

306-307:到插件内的IPlugin中调用其query方法,来获取IBinder对象并返回给外界。

具体代码如下:

其中mPlugins字段用来记录所有的插件信息,不管插件是否被加载,这里不再赘述。

PluginLoader类的query方法就是从刚才在加载插件时,从Entry中拿到IPlugin中调用其query方法,具体代码如下:

在步骤204和205中,可以实现跨进程获取IBinder对象。跨进程获取的要点是:

通过Provider来获取IPluginHost这个AIDL对象;

借由IPluginHost.query()方法来调用PluginFactory.query()方法。

其中,IPluginHost的获取可以通过SyncServiceManager.getService来获取。一旦拿到IPluginHost对象后,可直接调用PluginFactory.query方法,进而调用Entry.create方法中获取插件的接口的对象(即,mPlugin对象),之后,调用插件的接口的对象中的query方法获取IBinder对象。

此外,本发明实施例还可以定义IPlugin和插件初始化。作为插件接口定义方,定义供外界访问的IPlugin对象只需要复写IPlugin.query方法,并在Entry类中返回此对象即可。这里,还可以做插件初始化的一些操作,且一旦操作失败,则可以返回null,这将会告诉外界,插件加载失败。

具体代码如下:

若外界想获取IAccountManager的AIDL,只需这样调用即可:

其中第一个参数为插件名,第二个为模块名。拿到的IBinder对象需要再转换成IAccountManager后即可。

综上介绍,本发明实施例可以做到:

(1)只需要通过PluginFactory.query方法来获取AIDL,没有多余步骤;

(2)只需要定义IPlugin.query和设置返回值就可以定义AIDL,同样没有多余步骤;

(3)不仅支持当前进程,还可以跨进程到常驻进程里(当然,不仅仅局限于常驻,还可在UI、单独等)

(4)在Entry类的create方法内,还可以做些额外的初始化操作,方便插件做下一步操作。其所做的事情和Application可形成互补。

进一步地,在上文调用目标插件的接口的对象中的指定方法获取IBinder对象之后,可以利用获取的IBinder对象进行与目标插件进行通信,来实现相应的功能或任务。

Android的远程调用(即跨进程调用)就是通过IBinder实现的,IBinder是远程对象的基本接口,是为高性能而设计的轻量级远程调用机制的核心部分。但它不仅用于远程调用,也用于进程内调用。这个接口定义了与远程对象交互的协议。不要直接实现这个接口,而应该从Binder派生。IBinder的主要API是transact(),与它对应另一方法是Binder.onTransact()。第一个方法使调用者向远端的IBinder对象发送发出调用,第二个方法使调用方的远程对象能够响应接收到的调用。IBinder的API都是同步执行的,比如transact()直到对方的Binder.onTransact()方法调用完成后才返回。调用发生在进程内时无疑是这样的,而在进程间时,在IPC的帮助下,也是同样的效果。

通过transact()发送的数据是Parcel,Parcel是一种一般的缓冲区,除了有数据外还带有一些描述它内容的元数据。元数据用于管理IBinder对象的引用,这样就能在缓冲区从一个进程移动到另一个进程时保存这些引用。这样就保证了当一个IBinder被写入到Parcel并发送到另一个进程中,如果另一个进程把同一个IBinder的引用回发到原来的进程,那么这个原来的进程就能接收到发出的那个IBinder的引用。这种机制使IBinder和Binder像唯一标志符那样在进程间管理。

系统为每个进程维护一个存放交互线程的线程池。这些交互线程用于派送所有从另外进程发来的IPC调用。例如,当一个IPC从进程A发到进程B,A中那个发出调用的线程(这个应该不在线程池中)就阻塞在transact()中了。进程B中的交互线程池中的一个线程接收了这个调用,它调用Binder.onTransact(),完成后用一个Parcel来做为结果返回。然后进程A中的那个等待的线程在收到返回的Parcel后得以继续执行。实际上,另一个进程看起来就像是当前进程的一个线程,但不是当前进程创建的。

Binder机制还支持进程间的递归调用。例如,进程A执行自己的IBinder的transact()调用进程B的Binder,而进程B在其Binder.onTransact()中又用transact()向进程A发起调用,那么进程A在等待它发出的调用返回的同时,还会用Binder.onTransact()响应进程B的transact()。总之Binder造成的结果使得跨进程的调用与进程内的调用没什么区别。

基于上文各个实施例提供的插件加载方法,基于同一发明构思,本发明实施例还提供了一种插件加载装置。

图2示出了根据本发明一个实施例的插件加载装置的结构示意图。如图2所示,该装置至少可以包括加载模块210、创建模块220以及缓存模块230。

现介绍本发明实施例的插件加载装置的各组成或器件的功能以及各部分间的连接关系:

加载模块210,适于当宿主程序接收到加载插件的指令时,调用插件加载方法对目标插件进行加载;

创建模块220,与加载模块210相耦合,适于在加载目标插件的过程中,创建目标插件的入口类的对象;

缓存模块230,与创建模块220相耦合,适于利用所述入口类的对象,调用所述入口类中的指定方法缓存目标插件的接口的对象。

在本发明一实施例中,如图3所示,上文图2展示的装置还可以包括:

调用模块240,与缓存模块230相耦合,适于目标插件的接口的对象用于获取IBinder对象,当外部调用方需要获取目标插件的IBinder对象时,调用预先定义的预定义类中的指定方法;

第一获取模块250,与调用模块240相耦合,适于利用所述预定义类中的指定方法,从所述入口类中的指定方法中获取目标插件的接口的对象;

第二获取模块260,与第一获取模块250相耦合,适于调用目标插件的接口的对象中的指定方法获取IBinder对象。

在本发明一实施例中,如图3所示,上文图2展示的装置还可以包括:

通信模块270,与第二获取模块260相耦合,适于在所述第二获取模块260调用目标插件的接口的对象中的指定方法获取IBinder对象之后,利用获取的IBinder对象进行与所述目标插件进行通信。

在本发明一实施例中,所述目标插件的入口类为Entry类。

在本发明一实施例中,所述目标插件的接口为IPlugin接口,所述IPlugin接口的对象为mPlugin对象。

在本发明一实施例中,如图3所示,上文图2展示的装置还可以包括:

第三获取模块280,与创建模块220、缓存模块230相耦合,适于利用所述入口类的对象,反射获取所述入口类中的指定方法。

在本发明一实施例中,上述调用模块240还适于:

当外部调用方需要获取插件的IBinder对象时,判断所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程是否为同一进程;

若是,则直接调用预先定义的预定义类中的指定方法。

在本发明一实施例中,上述调用模块240还适于:

若所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程不为同一进程,则通过所述目标进程中的Provider获取宿主程序的接口的对象;

由宿主程序的接口的对象中的指定方法,调用预先定义的预定义类中的指定方法。

在本发明一实施例中,所述目标进程为常驻进程。

在本发明一实施例中,所述宿主程序的接口为IPluginHost接口。

在本发明一实施例中,上述第二获取模块260还适于:

调用目标插件的接口的对象中的指定方法;

根据module名字返回对应的IBinder对象。

在本发明一实施例中,上述加载模块210还适于:

将插件加载事件拆分为独立的至少一个加载阶段,其中,各个加载阶段对应不同的插件内容;

当宿主程序接收到加载插件的指令时,确定所述请求对应的目标加载阶段;

加载所述目标加载阶段对应的插件内容。

在本发明一实施例中,所述至少一个加载阶段包括下列至少之一:

插件信息的获取、插件资源的加载、插件代码的加载。

根据上述任意一个优选实施例或多个优选实施例的组合,本发明实施例能够达到如下有益效果:

本发明实施例提供的技术方案,当宿主程序接收到加载插件的请求时,调用插件加载方法对目标插件进行加载,在加载目标插件的过程中可以创建目标插件的入口类的对象,并利用入口类的对象,调用入口类中的指定方法缓存目标插件的接口的对象。由于该目标插件的接口的对象能够用于获取IBinder对象,因而当外部调用方需要获取目标插件的IBinder对象时,可以直接获取缓存的目标插件的接口的对象,并利用该目标插件的接口的对象来获取IBinder对象,进而可以利用获取的IBinder对象与目标插件进行通信。由此可见,本发明实施例能够充分利用Android系统的逻辑来实现在插件中快速、同步地获取IBinder对象,实现进程内或进程间的通信。

在此处所提供的说明书中,说明了大量具体细节。然而,能够理解,本发明的实施例可以在没有这些具体细节的情况下实践。在一些实例中,并未详细示出公知的方法、结构和技术,以便不模糊对本说明书的理解。

类似地,应当理解,为了精简本公开并帮助理解各个发明方面中的一个或多个,在上面对本发明的示例性实施例的描述中,本发明的各个特征有时被一起分组到单个实施例、图、或者对其的描述中。然而,并不应将该公开的方法解释成反映如下意图:即所要求保护的本发明要求比在每个权利要求中所明确记载的特征更多的特征。更确切地说,如下面的权利要求书所反映的那样,发明方面在于少于前面公开的单个实施例的所有特征。因此,遵循具体实施方式的权利要求书由此明确地并入该具体实施方式,其中每个权利要求本身都作为本发明的单独实施例。

本领域那些技术人员可以理解,可以对实施例中的设备中的模块进行自适应性地改变并且把它们设置在与该实施例不同的一个或多个设备中。可以把实施例中的模块或单元或组件组合成一个模块或单元或组件,以及此外可以把它们分成多个子模块或子单元或子组件。除了这样的特征和/或过程或者单元中的至少一些是相互排斥之外,可以采用任何组合对本说明书(包括伴随的权利要求、摘要和附图)中公开的所有特征以及如此公开的任何方法或者设备的所有过程或单元进行组合。除非另外明确陈述,本说明书(包括伴随的权利要求、摘要和附图)中公开的每个特征可以由提供相同、等同或相似目的的替代特征来代替。

此外,本领域的技术人员能够理解,尽管在此所述的一些实施例包括其它实施例中所包括的某些特征而不是其它特征,但是不同实施例的特征的组合意味着处于本发明的范围之内并且形成不同的实施例。例如,在权利要求书中,所要求保护的实施例的任意之一都可以以任意的组合方式来使用。

本发明的各个部件实施例可以以硬件实现,或者以在一个或者多个处理器上运行的软件模块实现,或者以它们的组合实现。本领域的技术人员应当理解,可以在实践中使用微处理器或者数字信号处理器(DSP)来实现根据本发明实施例的插件加载装置中的一些或者全部部件的一些或者全部功能。本发明还可以实现为用于执行这里所描述的方法的一部分或者全部的设备或者装置程序(例如,计算机程序和计算机程序产品)。这样的实现本发明的程序可以存储在计算机可读介质上,或者可以具有一个或者多个信号的形式。这样的信号可以从因特网网站上下载得到,或者在载体信号上提供,或者以任何其他形式提供。

应该注意的是上述实施例对本发明进行说明而不是对本发明进行限制,并且本领域技术人员在不脱离所附权利要求的范围的情况下可设计出替换实施例。在权利要求中,不应将位于括号之间的任何参考符号构造成对权利要求的限制。单词“包含”不排除存在未列在权利要求中的元件或步骤。位于元件之前的单词“一”或“一个”不排除存在多个这样的元件。本发明可以借助于包括有若干不同元件的硬件以及借助于适当编程的计算机来实现。在列举了若干装置的单元权利要求中,这些装置中的若干个可以是通过同一个硬件项来具体体现。单词第一、第二、以及第三等的使用不表示任何顺序。可将这些单词解释为名称。

至此,本领域技术人员应认识到,虽然本文已详尽示出和描述了本发明的多个示例性实施例,但是,在不脱离本发明精神和范围的情况下,仍可根据本发明公开的内容直接确定或推导出符合本发明原理的许多其他变型或修改。因此,本发明的范围应被理解和认定为覆盖了所有这些其他变型或修改。

本发明实施例还提供了A1、一种插件加载方法,包括:

当宿主程序接收到加载插件的请求时,调用插件加载方法对目标插件进行加载;

在加载目标插件的过程中,创建目标插件的入口类的对象;

利用所述入口类的对象,调用所述入口类中的指定方法缓存目标插件的接口的对象。

A2、根据A1所述的方法,其中,目标插件的接口的对象用于获取IBinder对象,所述方法还包括:

当外部调用方需要获取目标插件的IBinder对象时,调用预先定义的预定义类中的指定方法;

利用所述预定义类中的指定方法,从所述入口类中的指定方法中获取目标插件的接口的对象;

调用目标插件的接口的对象中的指定方法获取IBinder对象。

A3、根据A2所述的方法,其中,在调用目标插件的接口的对象中的指定方法获取IBinder对象之后,所述方法还包括:

利用获取的IBinder对象进行与所述目标插件进行通信。

A4、根据A1-A3中任一项所述的方法,其中,所述目标插件的入口类为Entry类。

A5、根据A1-A4中任一项所述的方法,其中,所述目标插件的接口为IPlugin接口,所述IPlugin接口的对象为mPlugin对象。

A6、根据A1-A5中任一项所述的方法,其中,还包括:

利用所述入口类的对象,反射获取所述入口类中的指定方法。

A7、根据A2-A6中任一项所述的方法,其中,当外部调用方需要获取目标插件的IBinder对象时,调用预先定义的预定义类中的指定方法,包括:

当外部调用方需要获取目标插件的IBinder对象时,判断所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程是否为同一进程;

若是,则直接调用预先定义的预定义类中的指定方法。

A8、根据A7所述的方法,其中,还包括:

若所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程不为同一进程,则通过所述目标进程中的Provider获取宿主程序的接口的对象;

由宿主程序的接口的对象中的指定方法,调用预先定义的预定义类中的指定方法。

A9、根据A8所述的方法,其中,所述目标进程为常驻进程。

A10、根据A8或A9所述的方法,其中,所述宿主程序的接口为IPluginHost接口。

A11、根据A1-A10中任一项所述的方法,其中,调用目标插件的接口的对象中的指定方法获取IBinder对象,包括:

调用目标插件的接口的对象中的指定方法;

根据module名字返回对应的IBinder对象。

A12、根据A1-A11中任一项所述的方法,其中,当宿主程序接收到加载插件的指令时,调用插件加载方法对目标插件进行加载,包括:

将插件加载事件拆分为独立的至少一个加载阶段,其中,各个加载阶段对应不同的插件内容;

当宿主程序接收到加载插件的指令时,确定所述请求对应的目标加载阶段;

加载所述目标加载阶段对应的插件内容。

A13、根据A12所述的方法,其中,所述至少一个加载阶段包括下列至少之一:

插件信息的获取、插件资源的加载、插件代码的加载。

本发明实施例还提供了B14、一种插件加载装置,包括:

加载模块,适于当宿主程序接收到加载插件的指令时,调用插件加载方法对目标插件进行加载;

创建模块,适于在加载目标插件的过程中,创建目标插件的入口类的对象;

缓存模块,适于利用所述入口类的对象,调用所述入口类中的指定方法缓存目标插件的接口的对象。

B15、根据B14所述的装置,其中,目标插件的接口的对象用于获取IBinder对象,所述装置还包括:

调用模块,适于当外部调用方需要获取目标插件的IBinder对象时,调用预先定义的预定义类中的指定方法;

第一获取模块,适于利用所述预定义类中的指定方法,从所述入口类中的指定方法中获取目标插件的接口的对象;

第二获取模块,适于调用目标插件的接口的对象中的指定方法获取IBinder对象。

B16、根据B15所述的装置,其中,还包括:

通信模块,适于在所述第二获取模块调用目标插件的接口的对象中的指定方法获取IBinder对象之后,利用获取的IBinder对象进行与所述目标插件进行通信。

B17、根据B14-B16中任一项所述的装置,其中,所述目标插件的入口类为Entry类。

B18、根据B14-B17中任一项所述的装置,其中,所述目标插件的接口为IPlugin接口,所述IPlugin接口的对象为mPlugin对象。

B19、根据B14-B18中任一项所述的装置,其中,还包括:

第三获取模块,适于利用所述入口类的对象,反射获取所述入口类中的指定方法。

B20、根据B15-B19中任一项所述的装置,其中,所述调用模块还适于:

当外部调用方需要获取目标插件的IBinder对象时,判断所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程是否为同一进程;

若是,则直接调用预先定义的预定义类中的指定方法。

B21、根据B20所述的装置,其中,所述调用模块还适于:

若所述外部调用方所在当前进程与即将返回所述目标插件的IBinder对象的接收方所在目标进程不为同一进程,则通过所述目标进程中的Provider获取宿主程序的接口的对象;

由宿主程序的接口的对象中的指定方法,调用预先定义的预定义类中的指定方法。

B22、根据B21所述的装置,其中,所述目标进程为常驻进程。

B23、根据B21或B22所述的装置,其中,所述宿主程序的接口为IPluginHost接口。

B24、根据B14-B23中任一项所述的装置,其中,所述第二获取模块还适于:

调用目标插件的接口的对象中的指定方法;

根据module名字返回对应的IBinder对象。

B25、根据B14-B24中任一项所述的装置,其中,所述加载模块还适于:

将插件加载事件拆分为独立的至少一个加载阶段,其中,各个加载阶段对应不同的插件内容;

当宿主程序接收到加载插件的指令时,确定所述请求对应的目标加载阶段;

加载所述目标加载阶段对应的插件内容。

B26、根据B25所述的装置,其中,所述至少一个加载阶段包括下列至少之一:

插件信息的获取、插件资源的加载、插件代码的加载。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1