发明内容
针对现有技术中存在的缺陷,本发明实施例的目的在于提供一种能够克服上述问题或者至少能够部分地解决上述问题的在安卓art环境中动态加载dex的方法及装置。
为实现上述目的,本发明的一个实施例中提供了一种在安卓art环境中动态加载dex的方法,该方法包括:
调用安卓art环境下操作系统的dex文件解析加载函数DexFile::OpenMemory,完成待加载的dex文件的底层解析与加载,得到加载后的dex文件的内存地址;
新建一个上层dex文件对象,将已完成底层加载的dex文件的内存地址赋值给所述上层dex文件对象的变量cookie,将上层dex文件对象作为dex类加载器BaseDexClassLoader的dex路径信息列表对象pathList中的dex文件数组dexElements的元素,插入到所述dex文件数组dexElements中;
通过dex类加载器BaseDexClassLoader完成dex文件数组dexElements中的元素所对应dex文件的动态加载。
优选的,如上所述的动态加载dex的方法,底层的操作是指通过本地编程语言完成的库或程序来完成的操作;上层的操作是指通过JAVA语言完成的库或程序来完成的操作;所述本地编程语言包括C或C++。
优选的,如上所述的动态加载dex的方法,所述调用安卓art环境下操作系统的dex文件解析加载函数DexFile::OpenMemory,完成待加载的dex文件的底层解析与加载,包括:
在安卓art环境下的动态链接库文件中查找dex文件加载解析函数,记录dex文件加载解析函数的地址;
将待加载的dex文件作为dex文件加载解析函数的参数,根据记录的dex文件加载解析函数的地址调用该函数,完成待加载的dex文件的解析与加载。
优选的,如上所述的动态加载dex的方法,所述动态链接库文件为安卓art环境下so库。
优选的,如上所述的动态加载dex的方法,所述上层dex文件对象为应用程序框架层dex文件对象dalvik/system/DexFile。
优选的,如上所述的动态加载dex的方法,通过dex类加载器BaseDexClassLoader完成dex文件的动态加载,包括:
通过dex类加载器BaseDexClassLoader调用其dex路径信息列表对象pathList,dex路径信息列表对象pathList遍历其dex文件数组dexElements中的元素,dex类加载器BaseDexClassLoader根据数组中的元素查找对应内存地址中的dex文件,依次完成每个dex文件的动态加载。
本发明的一个实施例中还提供了一种在安卓art环境中动态加载dex的装置,该装置包括:
系统底层加载模块,用于调用安卓art环境下操作系统的dex文件解析加载函数DexFile::OpenMemory,完成待加载的dex文件的底层解析与加载,得到加载后的dex文件的内存地址;
dex元素添加模块,用于新建一个上层dex文件对象,将已完成底层加载的dex文件的内存地址赋值给上层dex文件对象的变量cookie,将上层dex文件对象作为dex类加载器BaseDexClassLoader的dex路径信息列表对象pathList中的dex文件数组dexElements的元素,插入到所述dex文件数组dexElements中;
Dex文件动态加载模块,用于通过dex类加载器BaseDexClassLoader完成dex文件数组dexElements中的元素所对应的dex文件的动态加载。
优选的,如上所述的动态加载dex的装置,底层的操作是指通过本地编程语言完成的库或程序来完成的操作;上层的操作是指通过JAVA语言完成的库或程序来完成的操作;所述本地编程语言包括C或C++。
优选的,如上所述的动态加载dex的装置,所述系统底层加载模块包括:
系统加载函数查找单元,用于在安卓art环境下的动态链接库文件中查找dex文件加载解析函数,记录该dex文件加载解析函数的地址;
Dex文件底层加载单元,用于将待加载的dex文件作为dex文件加载解析函数的参数,根据所记录的dex文件加载解析函数的地址调用该函数,完成待加载的dex文件的解析与加载。
优选的,如上所述的动态加载dex的装置,所述动态链接库文件为安卓art环境下so库。
优选的,如上所述的动态加载dex的装置,所述上层dex文件对象为应用程序框架层dex文件对象dalvik/system/DexFile。
优选的,如上所述的动态加载dex的装置,Dex文件动态加载模块包括:
路径信息列表调用单元,用于通过dex类加载器BaseDexClassLoader调用其dex路径信息列表对象pathList;
Dex文件数组遍历单元,用于dex类加载器BaseDexClassLoader调用其dex路径信息列表对象pathList时,dex路径信息列表对象pathList遍历其dex文件数组dexElements中的元素;
Dex文件动态加载单元,用于dex类加载器BaseDexClassLoader根据所述数组中的元素查找对应内存地址中的dex文件,依次完成每个dex文件的动态加载。
本发明的有益效果在于:本发明实施例中所提供的安卓art环境中动态加载dex的方法及装置,通过操作系统的dex文件解析加载函数实现了dex文件的底层解析与加载,将加载后的dex文件的内存地址作为上层dex文件对象的变量,将上层dex文件对象作为dex类加载器BaseDexClassLoader中的dexElements的元素,从而通过dex类加载器实现了对dexElements中的元素所对应dex文件的动态加载。本发明实施例中所提供的方案,实现了安卓art环境下对dex文件的动态加载,解决了现有dalvik环境下动态加载dex文件的方案不适用于art环境的问题,且该方案使用系统函数完成dex文件的底层解析与加载,保证了解析加载的准确度,大大降低了开发人员内的工作量。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,均属于本发明保护的范围。
图1示出了本发明的一个实施例中提供的一种在安卓art环境中动态加载dex的方法的流程示意图,由图中可以看出,该方法包括以下步骤:
步骤S100:调用art环境下操作系统的dex文件解析加载函数完成待加载的dex文件的底层解析与加载,得到加载后的dex文件的内存地址;
在ART环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。Android的运行时从Dalvik虚拟机替换成ART虚拟机,并不要求开发者要重新将自己的应用直接编译成目标机器码,也就是说,开发者开发出的应用程序经过编译和打包之后,仍然是一个包含dex字节码的APK文件。既然应用程序包含的仍然是dex字节码,而ART虚拟机需要的是本地机器码,这就必然要有一个在应用安装完成dex文件的动态加载。
为了实现对dex文件的动态加载,本实施例中,首先完成dex文件的底层加载,具体加载方式为:
通过调用安卓art环境下操作系统的dex文件解析加载函数DexFile::OpenMemory,来完成待加载dex文件的底层解析与加载,将待加载dex文件映射到内存中,得到待加载dex文件的内存地址。即通过系统函数DexFile::OpenMemory完成dex文件的底层加载。
其中,底层即本地框架层、Native层,底层的操作是指通过本地编程语言完成的库或程序来完成的操作;上层即Java层,上层的操作是指通过JAVA语言完成的库或程序来完成的操作;所述本地编程语言包括但不限于C或C++。为了实现上层的dex文件动态加载,首先需要底层解析dex文件得到字节码,然后进行加载到内存中的,然后通过底层与上层之间的通信调用,完成上层的dex文件的动态加载。
在本发明的一个实施例中,所述调用安卓art环境下操作系统的dex文件解析加载函数DexFile::OpenMemory,完成待加载的dex文件的底层解析与加载,具体方式包括:
在安卓art环境下的动态链接库文件中查找dex文件加载解析函数DexFile::OpenMemory,记录dex文件加载解析函数的地址;
将待加载的dex文件作为dex文件加载解析函数的参数,根据记录的dex文件加载解析函数的地址调用该参数,完成待加载的dex文件的解析与加载。
通过该方式,完成了class.dex中多dex文件的底层解析与加载,将多dex文件分别加载到内存中,并记录各dex文件的地址。
在实际操作中,将查找到的dex文件加载解析函数DexFile::OpenMemory的地址记为A,将需要加载的dex文件作为A的参数调用函数A,返回的值记为B,B即为已解析的各dex文件的内存地址。
其中,所述art环境下的动态链接库文件为安卓art环境下so库,即ibart.so(该名称可变)。
本实施例中,通过系统函数DexFile::OpenMemory完成dex文件的底层加载,有效保障了dex文件解析加载的效率和准确性。
步骤S200:新建上层dex文件对象,将已完成底层加载的dex文件的内存地址赋值给所述上层dex文件对象的变量cookie,将上层dex文件对象插入到dex类加载器的dex路径信息列表对象的dex文件数组dexElements中;
步骤S300:通过dex类加载器BaseDexClassLoader完成dex文件数组dexElements中的元素所对应dex文件的动态加载。
为了实现上层即JAVA层对底层已加载dex文件的调用,需要创建一个上层对底层调用的接口,以实现上层对底层的调用。本实施例中,实现方式为:
新建一个上层dex文件对象,将已完成底层加载的dex文件的内存地址赋值给所述上层dex文件对象的变量cookie,将上层dex文件对象作为dex类加载器BaseDexClassLoader的dex路径信息列表对象pathList中的dex文件数组dexElements的元素,插入到所述dex文件数组dexElements中。
其中,所述上层dex文件对象为应用程序框架层dex文件对象dalvik/system/DexFile,记为C,新建dalvik/system/DexFile对象,即创建一个DexFile的实例,将已完成底层解析与加载的各dex文件的内存地址赋值给上层dex文件对象的变量cookie,即将B赋值给C的变量cookie。
所述变量cookie,其实是一个dex文件指针,JAVA层的dex类加载器根据该指令就可以查找到对应的内存中的dex内容。
将上层dex文件对象添加到dex文件数组dexElements后,即可通过dex类加载器BaseDexClassLoader完成dex文件数组dexElements中的元素所对应dex文件的动态加载,具体加载方式包括:
通过dex类加载器BaseDexClassLoader调用其dex路径信息列表对象pathList,dex路径信息列表对象pathList遍历其dex文件数组dexElements中的元素,dex类加载器BaseDexClassLoader根据数组中的元素查找对应内存地址中的dex文件,依次完成每个dex文件的动态加载。
一个dex文件对应一个cookie值,将cookie作为上层文件对象dalvik/system/DexFile的变量,dex类加载器BaseDexClassLoader通过dexElements中的元素即上层dex文件对象,即可根据上层dex文件对象的变量cookie在相应的内存中查找到对应的dex文件,完成dex文件的动态加载。
本发明实施例中所述的安卓art环境中动态加载dex的方法,通过调用art运行环境下的系统函数DexFile::OpenMemory完成dex文件的底层解析加载,将dex文件加载到内存中,保证了底层操作的准确性,且大大降低了开发人员的工作量,提供了一种新的安卓art环境中动态加载dex的方案。
对应于图1中所示的动态加载dex的方法,本发明的一个实施例中还提供了一种在安卓art环境中动态加载dex的装置,如图2所示,该装置主要包括系统底层加载模块100、dex元素添加模块200和Dex文件动态加载模块300。其中:
系统底层加载模块100,用于调用安卓art环境下操作系统的dex文件解析加载函数DexFile::OpenMemory,完成待加载的dex文件的底层解析与加载,得到加载后的dex文件的内存地址;
dex元素添加模块200,用于新建一个上层dex文件对象,将已完成底层加载的dex文件的内存地址赋值给上层dex文件对象的变量cookie,将上层dex文件对象作为dex类加载器BaseDexClassLoader的dex路径信息列表对象pathList中的dex文件数组dexElements的元素,插入到所述dex文件数组dexElements中;
Dex文件动态加载模块300,用于通过dex类加载器BaseDexClassLoader完成dex文件数组dexElements中的元素所对应的dex文件的动态加载。
所述系统底层加载模块100用于完成dex文件的底层解析与加载,完成dex文件到内存的映射。其中,底层操作与上层操作是相对的,所谓底层即本地框架层、Native层,上层即Java层,底层的操作是指通过本地编程语言完成的库或程序来完成的操作;上层的操作是指通过JAVA语言完成的库或程序来完成的操作;所述本地编程语言包括但不限于C或C++。
本实施例中所提供的在安卓art环境中动态加载dex的装置,由系统底层加载模块100首先完成dex文件的底层解析与加载,通过dex元素添加模块200将以dex文件的内存地址为变量cookie的上层dex文件对象作为元素插入到dex类加载器BaseDexClassLoader的dex文件数组dexElements中,Dex文件动态加载模块300通过Dex类加载器BaseDexClassLoader即可完成dex文件数组dexElements元素对应的dex文件的动态加载。其中,所述上层dex文件对象为应用程序框架层dex文件对象dalvik/system/DexFile。
在本发明的一个实施例中,所述系统底层加载模块100包括系统加载函数查找单元110和Dex文件底层加载单元120,如图3所示。其中:
系统加载函数查找单元110,用于在安卓art环境下的动态链接库文件中查找dex文件加载解析函数DexFile::OpenMemory,记录该dex文件加载解析函数的地址所述动态链接库文件为安卓art环境下so库,即libart.so(该名称可变)。
Dex文件底层加载单元120,用于将待加载的dex文件作为dex文件加载解析函数的参数,根据所记录的dex文件加载解析函数的地址调用该参数,完成待加载的dex文件的解析与加载。
本实施例中,通过系统加载函数查找单元110在libart.so库中寻找到dex文件加载解析函数DexFile::OpenMemory,由Dex文件底层加载单元120将待加载dex文件作为DexFile::OpenMemory的参数,完成了dex文件的底层解析,得到字节码,并加载到内存中。
在本发明的一个实施例中,所述Dex文件动态加载模块300包括路径信息列表调用单元310、Dex文件数组遍历单元320和Dex文件动态加载单元330,如图4所示。其中:
路径信息列表调用单元310,用于通过dex类加载器BaseDexClassLoader调用其dex路径信息列表对象pathList;
Dex文件数组遍历单元320,用于dex类加载器BaseDexClassLoader调用其dex路径信息列表对象pathList时,dex路径信息列表对象pathList遍历其dex文件数组dexElements中的元素;
Dex文件动态加载单元330,用于dex类加载器BaseDexClassLoader根据所述数组中的元素查找对应内存地址中的dex文件,依次完成每个dex文件的动态加载。
本实施例中,dex类加载器BaseDexClassLoader根据dex文件数组dexElements中的上层dex文件对象的变量cookie,即可找到该cookie对应的内存地址中的dex文件,完成dex字节码的动态加载。
需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。
本说明书中的各个实施例均采用相关的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于装置实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
本领域普通技术人员可以理解实现上述装置实施方式中各部分的全部或部分可以以硬件实现,或者以在一个或多个硬件上运行的软件模块来实现,可以对实施例中的设备中的模块进行自适应性地改变并且把它们设置在与该实施例不同的一个或多个设备中,可以把实施例中的模块或单元或组件组合成一个模块或单元或组件,以及此外可以把它们分成多个子模块或子单元或子组件。除了特征和/或过程或者单元中的至少一些是相互排斥之外,可以采用任何组合对本说明书(包括伴随的权利要求、摘要和附图)中公开的所有特征以及如此公开的任何方法或者设备的所有过程或单元进行组合。方法实施方式中的全部或部分步骤是可以通过程序来指令相关的硬件来完成。本领域技术人员应该明白,本发明所述的方法和装置并不限于具体实施方式中所述的实施例,上面的具体描述只是为了解释本发明的目的,并非用于限制本发明。本领域技术人员根据本发明的技术方案得出其他的实施方式,同样属于本发明的技术创新范围,本发明的保护范围由权利要求及其等同物限定。
在本发明的一个实施例中公开了:A1、一种在安卓art环境中动态加载dex的方法,所述方法包括:
调用安卓art环境下操作系统的dex文件解析加载函数DexFile::OpenMemory,完成待加载的dex文件的底层解析与加载,得到加载后的dex文件的内存地址;
新建一个上层dex文件对象,将已完成底层加载的dex文件的内存地址赋值给所述上层dex文件对象的变量cookie,将上层dex文件对象作为dex类加载器BaseDexClassLoader的dex路径信息列表对象pathList中的dex文件数组dexElements的元素,插入到所述dex文件数组dexElements中;
通过dex类加载器BaseDexClassLoader完成dex文件数组dexElements中的元素所对应dex文件的动态加载。
A2、根据A1所述的动态加载dex的方法,底层的操作是指通过本地编程语言完成的库或程序来完成的操作;上层的操作是指通过JAVA语言完成的库或程序来完成的操作;所述本地编程语言包括C或C++。
A3、根据A1所述的动态加载dex的方法,所述调用安卓art环境下操作系统的dex文件解析加载函数DexFile::OpenMemory,完成待加载的dex文件的底层解析与加载,包括:
在安卓art环境下的动态链接库文件中查找dex文件加载解析函数,记录dex文件加载解析函数的地址;
将待加载的dex文件作为dex文件加载解析函数的参数,根据记录的dex文件加载解析函数的地址调用该函数,完成待加载的dex文件的解析与加载。
A4、根据A3所述的动态加载dex的方法,所述动态链接库文件为安卓art环境下so库。
A5、根据A1所述的动态加载dex的方法,所述上层dex文件对象为应用程序框架层dex文件对象dalvik/system/DexFile。
A6、根据A5所述的动态加载dex的方法,通过dex类加载器BaseDexClassLoader完成dex文件的动态加载,包括:
通过dex类加载器BaseDexClassLoader调用其dex路径信息列表对象pathList,dex路径信息列表对象pathList遍历其dex文件数组dexElements中的元素,dex类加载器BaseDexClassLoader根据数组中的元素查找对应内存地址中的dex文件,依次完成每个dex文件的动态加载。
本发明的一个实施例中公开了:B7、一种在安卓art环境中动态加载dex的装置,所述装置包括:
系统底层加载模块,用于调用安卓art环境下操作系统的dex文件解析加载函数DexFile::OpenMemory,完成待加载的dex文件的底层解析与加载,得到加载后的dex文件的内存地址;
dex元素添加模块,用于新建一个上层dex文件对象,将已完成底层加载的dex文件的内存地址赋值给上层dex文件对象的变量cookie,将上层dex文件对象作为dex类加载器BaseDexClassLoader的dex路径信息列表对象pathList中的dex文件数组dexElements的元素,插入到所述dex文件数组dexElements中;
Dex文件动态加载模块,用于通过dex类加载器BaseDexClassLoader完成dex文件数组dexElements中的元素所对应的dex文件的动态加载。
B8、根据B7所述的动态加载dex的装置,底层的操作是指通过本地编程语言完成的库或程序来完成的操作;上层的操作是指通过JAVA语言完成的库或程序来完成的操作;所述本地编程语言包括C或C++。
B9、根据B7所述的动态加载dex的装置,所述系统底层加载模块包括:
系统加载函数查找单元,用于在安卓art环境下的动态链接库文件中查找dex文件加载解析函数,记录该dex文件加载解析函数的地址;
Dex文件底层加载单元,用于将待加载的dex文件作为dex文件加载解析函数的参数,根据所记录的dex文件加载解析函数的地址调用该函数,完成待加载的dex文件的解析与加载。
B10、根据B9所述的动态加载dex的装置,所述动态链接库文件为安卓art环境下so库。
B11、根据B7所述的动态加载dex的装置,所述上层dex文件对象为应用程序框架层dex文件对象dalvik/system/DexFile。
B12、根据B11所述的动态加载dex的装置,Dex文件动态加载模块包括:
路径信息列表调用单元,用于通过dex类加载器BaseDexClassLoader调用其dex路径信息列表对象pathList;
Dex文件数组遍历单元,用于dex类加载器BaseDexClassLoader调用其dex路径信息列表对象pathList时,dex路径信息列表对象pathList遍历其dex文件数组dexElements中的元素;
Dex文件动态加载单元,用于dex类加载器BaseDexClassLoader根据所述数组中的元素查找对应内存地址中的dex文件,依次完成每个dex文件的动态加载。
显然,本领域的技术人员可以对本发明进行各种改动和变型而不脱离本发明的精神和范围。这样,倘若本发明的这些修改和变型属于本发明权利要求及其同等技术的范围之内,则本发明也意图包含这些改动和变型在内。