CN108228266A - 一种Android插件框架下不同插件间启动Fragment组件的方法和装置 - Google Patents
一种Android插件框架下不同插件间启动Fragment组件的方法和装置 Download PDFInfo
- Publication number
- CN108228266A CN108228266A CN201611155111.5A CN201611155111A CN108228266A CN 108228266 A CN108228266 A CN 108228266A CN 201611155111 A CN201611155111 A CN 201611155111A CN 108228266 A CN108228266 A CN 108228266A
- Authority
- CN
- China
- Prior art keywords
- plug
- components
- fragment
- class
- fragment components
- 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.)
- Granted
Links
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/445—Program loading or initiating
- G06F9/44521—Dynamic linking or loading; Link editing at or after load time, e.g. Java class loading
- G06F9/44526—Plug-ins; Add-ons
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Stored Programmes (AREA)
Abstract
本申请公开了一种Android插件框架下不同插件间启动Fragment组件的方法,包括:系统接收到向Activity组件上添加Fragment组件的命令;根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名;根据所述插件包名安装运行所述插件包;使用所述插件包的类加载器加载运行所述Fragment组件。通过本申请中的方案,解决了现有技术不支持Activity组件启动不同插件中Fragment组件的问题,使应用程序开发者能够在插件化环境下,通过直接使用Fragment组件实现多终端屏幕分辨率适配,从而充分发挥Fragment组件在屏幕适配方面的显著优势,同时,简化了Android客户端应用程序的代码架构,显著减少不必要的工作量,提高了工作效率。
Description
技术领域
本申请涉及智能終端屏幕显示领域,具体涉及一种用于不同Android插件间启动Fragment组件的方法。
背景技术
当前国内Android手机应用软件发展迅速,其中很多大型的应用软件在业务快速发展过程中,遇到2个通用典型问题需要解决:1.从技术上讲,业务逻辑的复杂导致代码量急剧膨胀,各大厂商陆续出到单个应用程序方法数限制上限65536;2.在业务层面上,应用程序更新迭代加快,新的应用程序往往有其时效性,然而功能模块的解耦以及维护团队的分离也是大势所趋,一个应用程序的不同模块往往由多个不同的团队维护,如果每个模块升级新功能都需要对整个应用程序进行升级,则需要较长的时间成本,严重影响应用程序的开发效率。Android插件化技术在此背景下应运而生。
目前国内有很多插件化技术框架被广泛应用,具体通过如下方法完成:打包阶段生成多个插件APK和一个主APK;主APK在启动阶段初始化插件技术框架;主APK通过Android四大基本组件(Activity,Service,BroadcastReceiver,ContentProvider)调用插件APK;插件技术框架安装插件APK然后执行。
所述插件技术框架所运行的原理,主要有如下两种:
静态代理模式,如dynamic-load-APK、Direct-Load-APK等插件技术框架。这种模式的插件技术框架的主要原理是通过在宿主APK中定义Activity组件,代理插件中的Activity组件所有生命周期,保证插件Activity组件正常运行;
动态拦截hook模式,如360DroidPlugin、small等插件技术框架,这种模式的插件技术框架的主要原理是通过动态拦截Android系统接口或方法,从底层实现插件安装升级。
另一方面,Android系统运行在各种各样的设备中,有小屏幕的手机、超大屏幕的平板甚至电视。针对屏幕尺寸的差距,很多情况下,开发者先针对手机开发一套应用程序,然后拷贝一份,修改布局以适应其他屏幕尺寸的设备,这很大程度上增加了开发者的工作量,延长了开发周期。为了解决这样的问题,Android 3.0推出了Fragment组件。Fragment的含义为“碎片”,Fragment组件承担一部分原先由Activity组件承担的工作;通过Fragment组件,可以将屏幕分解为多个Fragment(碎片),同时负责控制Activity组件基础上显示View空间以及它们之间的逻辑。通过Fragment组件可以将屏幕碎片化为多个Fragment后,Activity组件只需要花精力去管理当前屏幕内应该显示哪些Fragments,以及应该对它们进行如何布局就行了。也就是,通过Fragment组件可以组合一系列有关联的UI组件,并管理它们之间的逻辑,而Activity组件负责在不同屏幕下(例如横竖屏)布局不同的Fragments组件的组合。同时,Fragment组件的使用特性,使其在客户端代码架构组织、多终端屏幕分辨率适配等方面发挥着重要作用。
在现有技术下,Fragement组件有静态使用模式和动态使用模式两种启动模式。
所述静态使用模式是使用Fragment组件最简单的一种方式,把Fragment组件当成普通的控件,直接写在Activity组件的布局文件中;
所述动态使用模式是通过编程方式,使用系统类FragmentManager直接将Fragment添加到Activity组件中,以实现动态的加载。
不论静态启动模式还是动态启动模式,Fragement组件最终都是嵌入Activity组件中,运行生命周期受Activity组件控制。
在Android插件化的大背景下,Fragment组件也越来越多地在插件化技术中应用。目前插件包定义的Fragment组件经常与插件内部Activity组件配合使用,与标准APK调用方式类似,绝大部分插件化技术框架都能够支持。
然而,在实际业务需求中,不同插件间Fragment组件与Activity组件配合使用的场景越来越多,Activity组件、Fragment组件很可能被分配到不同的插件模块中,由于Fragment组件不是Android系统标准的四大组件之一,此时Android系统将无法找到Fragment组件,从而使Activity组件无法正常调用处于其他组件中的Fragment组件。这样,就会造成以下问题:
不同插件之间无法实现相互调用Fragment组件,即Fragment组件只能在插件内部使用,这极大地限制了Fragment组件的使用场景。
在多终端屏幕分辨率适配时,只能使用自定义view或者Activity组件实现类似Fragment组件的功能,而Fragment组件在屏幕适配方面的显著优势无法得到充分的发挥。
在一个Android客户端应用程序的代码架构模式设计中,不得不考虑上述问题,开发者需要更复杂的代码逻辑,耗费更多的脑力和体力劳动,显著增加了不必要的工作量。
发明内容
本申请提供一种Android插件框架下不同插件间启动Fragment组件的方法和装置,以解决现有技术不支持Activity组件启动不同插件中Fragment组件的问题。
本申请提供一种Android插件框架下不同插件间启动Fragment组件的方法,包括:
系统接收到向Activity组件上添加Fragment组件的命令;
根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名;
根据所述插件包名安装运行所述插件包;
使用所述插件包的类加载器加载运行所述Fragment组件。
优选的,所述根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名的步骤,所述预定的方法为如下方法:
启动预先自定义的类加载器;
所述自定义的类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名。
优选的,所述自定义类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名采用如下方式实现:复写所述自定义类加载器中findClass方法,实现对所述预先定义好的插件清单文件的读取;在读取的插件清单文件中,查找所述Fragment组件的类名对应的插件包名。
优选的,所述启动预先自定义类加载器的过程是通过将代理hook系统类加载器PathClassLoader,替换成自定义类加载器实现启动的。
优选的,所述根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名的步骤,所述预定的方法为如下方法:
读取预先在客户端硬编码中定义好的所述Fragment组件的类名与其所在插件包名映射,获得其所在的插件包名。
优选的,在所述插件包的类加载器加载运行所述Fragment组件的步骤之后,检测所述Fragment组件是否加载成功,若否,则执行以下步骤:
所述Fragment组件被替换成预先在主APK定义的代理类;
对所述代理类执行实例化,通过反射机制在其构造函数中获取所述Fragment组件的类名;
通过所述Fragment组件的类名,获得对应所述Fragment组件的URL链接;
实例化系统WebviewFragment组件,将所述URL链接设置进该组件;
将所述WebviewFragment组件添加到Activity组件中,替换所述代理类;或者,
将所述WebviewFragment组件覆盖在所述代理类的上面,并执行所述WebviewFragment组件。
优选的,所述通过所述Fragment组件的类名,获得对应所述Fragment组件的URL链接,通过如下方法中的一种实现:
读取配置文件中Fragment组件的类名与其所对应的URL链接的映射关系,通过Fragment组件的名称映射,获得对应所述Fragment组件的URL链接;或,
将所述Fragment组件的类名传入预先设定好的服务器端,获得服务器端输出的对应所述Fragment组件的URL链接;或,
读取预先在客户端硬编码中定义好的Fragment组件的类名与URL链接映射,获得对应所述Fragment组件的URL链接。
本申请同时提供了一种Android插件框架下不同插件间启动Fragment组件的装置,包括:
接收单元,用于接收来自系统的向Activity组件上添加Fragment组件的命令;
匹配单元,用于根据所述接收单元中Fragment组件的类名,并采用预定的方法,获得其所在的插件包名;
安装单元,用于安装所述匹配单元提供的插件包名的插件包;
运行单元,用于使用所述安装完成的插件包中的类加载器加载运行所述Fragment组件。
优选的,包括:
启动加载器单元,用于启动预先自定义的类加载器;
查找单元,用于所述启动加载器单元中所述自定义类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名。
优选的,所述查找单元中所述启动加载器单元中所述自定义类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名采用如下方式实现:复写所述自定义类加载器中findClass方法,实现对所述预先定义好的插件清单文件的读取;在读取的插件清单文件中,查找所述Fragment组件的类名对应的插件包名。
优选的,所述启动加载器单元启动预先自定义类加载器的过程是通过将代理hook系统类加载器PathClassLoader,替换成自定义类加载器实现启动。
优选的,包括硬编码读取单元,用于读取预先在客户端硬编码中定义好的所述Fragment组件的类名与其所在插件包名映射,获得其所在的插件包名。
优选的,包括检测单元,用于在所述运行单元加载运行所述安装单元安装完成的所述插件包中所述Fragment组件后,检测所述Fragment组件是否加载成功,若否,则包括:
替换单元,用于将所述Fragment组件被替换成预先在主APK定义的代理类;
获取类名单元,用于对所述替换单元提供的所述代理类执行实例化,通过反射机制在其构造函数中获取所述替换单元中所述Fragment组件的类名;
获取URL链接单元,用于通过所述获取类名单元提供的所述Fragment组件的类名,获得对应所述Fragment组件的URL链接;
实例化WebviewFragment单元,用于实例化系统WebviewFragment组件,将所述获取URL链接单元提供的所述URL链接设置进该组件;
代理类替换单元,用于将所述实例化WebviewFragment单元中所述WebviewFragment组件添加到Activity组件中,替换所述代理类;或者,
覆盖单元,用于将所述实例化WebviewFragment单元中所述WebviewFragment组件覆盖在所述代理类的上面,并执行所述WebviewFragment组件。
本申请还提供了一种电子设备,该电子设备支持Android系统,包括:
处理器;以及
存储器,用于存储一种Android插件框架下不同插件间启动Fragment组件的程序,该设备通电并通过所述处理器运行所述Android插件框架下不同插件间启动Fragment组件的程序后,执行下述步骤:
系统接收到向Activity组件上添加Fragment组件的命令;
根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名;
根据所述插件包名安装运行所述插件包;
所述插件包的类加载器加载运行所述Fragment组件。
与现有技术相比,本申请具有以下优点:
本发明通过对Android系统Fragment组件运行机制的梳理和研究,提供一套根据Fragment组件类名匹配其所在插件包,进而安装插件包,从而保证插件间Fragment组件正常启动的方案。该方案突破了Android系统对插件化技术的限制,很好的支持插件间启动Fragment组件,使应用程序开发人员以系统原生的方式去开发Fragment组件。
由于本申请提供的技术实现了Activity组件可以调用不同插件的Fragment组件,有效拓宽了插件化技术应用场景。
采用本申请提供的技术方案,能够在插件化环境下,通过直接使用Fragment组件实现多终端屏幕分辨率适配,从而充分发挥Fragment组件在屏幕适配方面的显著优势。
由于本申请实现了Activity组件调用不同插件的Fragment组件,简化了Android客户端应用程序的代码架构,使应用程序开发者能够以系统原生的方式去开发Fragment组件,提高了工作效率,显著减少不必要的工作量。
附图说明
图1是本申请的Android插件框架下不同插件间启动Fragment组件的方法第一实施例的流程图。
图2是本申请的读取插件清单文件的流程图。
图3是本申请的Android插件框架下不同插件间启动Fragment组件的方法第二实施例的流程图。
图4是本申请的Android插件框架下不同插件间启动Fragment组件的装置实施例的示意图
具体实施方式
在下面的描述中阐述了很多具体细节以便于充分理解本申请。但是本申请能够以很多不同于在此描述的其它方式来实施,本领域技术人员可以在不违背本申请内涵的情况下做类似推广,因此本申请不受下面公开的具体实施的限制。
如图1所示,其为本申请提供的一种Android插件框架下不同插件间启动Fragment组件的方法第一实施例的流程图,具体包括以下步骤:
S101:系统接收到向Activity组件上添加Fragment组件的命令。
本步骤为本实施例的启动步骤;即系统接收到向Activity组件上添加Fragment组件的命令使本方法整个流程开始启动。
所述系统本实施例特指Android系统,一个Android系统是由相应的硬件和软件构造的一个支持各种Android系统下的APP应用程序使其得以运行的智能设备应用环境。Android系统是智能设备中常用的一种操作系统,为本领域技术人员所熟知,在此不予详述。
Android系统包含多种组件。所述Activity组件是Android组件中最基本也是最为常用的四大组件之一,Activity组件的功能是为使用者提供一个可视界面,方便使用者操作,比如拨打电话、照相、发邮件或者是使用地图等各种使用场景下的可视界面。在一个Android应用程序中,一个Activity组件通常就是一个单独的屏幕,它上面可以显示一些控制项,也可以监听使用者的事件并作出相应的回应。
所述Fragment组件是Android系统中的另外一个组件,但并非基本组件。Android在3.0这个版本中(API Level“Honeycomb”)引入了Fragment的概念,这个组件的主要作用是支持在大屏幕上更为动态和灵活的UI设计,例如平板电脑。由于平板电脑的屏幕要比手持电话的大许多,这样就有更多的空间去组合和交换UI组件。有了Fragment组件,开发者可以不必去管理视图体系的复杂变化,通过将Activity组件的布局分割成若干个Fragment组件,并且在运行时编辑Activity组件的呈现,这些变化会被保存在由Activity组件管理的后台栈里面。如Android开发文档所述,Fragment组件的功能是表现Activity组件中用户界面的一个行为或者是一部分。开发者可以在一个单独的Activity组件上把多个Fragment组件组合成为一个多区域的UI,并且可以在多个Activity组件中再使用;开发者也可以把Fragment组件当作Activity组件的一个模块零件,它有自己的生命周期,接收它自己的输入事件,并且可以在Activity组件运行时添加或者删除。
Fragment组件必须总是被嵌入到一个Activity组件之中使用,并且Fragment组件的生命周期直接受其宿主Activity组件的生命周期的影响。例如,一旦Activity组件被暂停,它里面所有的Fragment组件也被暂停,一旦Activity组件被销毁,它里面所有的Fragment组件也被销毁。然而,当Activity组件正在运行时(处于resumed的生命周期状态),可以单独的操控每个Fragment组件,比如添加或者删除。当执行这样一项事务时,可以将它添加到后台的一个栈中,这个栈由Activity组件管理着——Activity组件里面的每个后台栈内容实体是Fragment组件发生过的一条事务记录。这个后台栈允许用户通过按BACK键回退一项Fragment组件事务(往后导航)。
本步骤所述向Activity组件上添加Fragment组件的命令,是指被预定加载在Activity组件上的Fragment组件的方法被触发。
所述命令可以是应用程序启动时需加载的Fragment组件在应用程序启动过程中自动被触发;也可以是在应用程序运行中用户的某一个操控动作引起的包含加载Fragment组件的回应所触发。
S102:根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名。
每一个Fragment组件都是一个类,在开发过程中,要在Activity组件中添加一个Fragment组件,就必须创建一个Fragment类的子类(或是继承自它的子类)。因此,每一个Fragment组件都以类的形式存在于插件包中,它们可以被分配于相同的插件包内,也可以被分配到不同的插件包中。例如:某个应用程序在平板上运行时使用Fragment组件1在左边展示一个文章列表,Fragment组件2在右边展示文章,就需要写一个继承于Fragment类的子类Fragment1并在所述子类Fragment1中定义所述Fragment组件1的样式和功能;写一个继承于Fragment类的子类Fragment2并在所述子类Fragment2中定义所述Fragment组件2的样式和功能。由于每个Fragment组件必须嵌入到Activity组件中,而Activity组件与Fragment组件不一定在同一个包中,例如,前述应用程序Fragment组件1在第一个插件包中,Fragment组件2在第二个插件包中,而嵌入所述Fragment组件1和所述Fragment组件2的Activity组件却在主APK中,此时它们所在的插件包名就不同了。因此,在步骤S101中系统接收到向Activity组件上添加Fragment组件的命令后,执行本步骤,目的是寻找所述Fragment组件所在的插件包。
所述预定的方法,即是指通过Fragment组件的类名寻找其所在的插件包名的方法,Fragment组件的类名与其所在插件包名映射关系有多种存储的方法,以下提供几种相关存储方法。
一种可能的存储方法是开发者在客户端硬编码中定义,也就是在开发过程中将Fragment组件的类名与其所在的插件包名的映射以代码的形式定义保存;这样,在需要根据所述Fragment组件的类名,获得其所在的插件包名的情况下,可以通过读取预先在客户端硬编码中定义好的所述Fragment组件的类名与其所在插件包名映射,获得其所在的插件包名。
另外一种更为可行的存储方法,是将Fragment组件的类名与其所在的插件包名的映射以插件清单文件的形式存储起来,这种存储方法更便于以后修改。在这种方案下根据所述Fragment组件的类名,获得其所在的插件包名的具体过程是:启动预先自定义的类加载器;所述自定义的类加载器根据所述Fragment组件的类名查找并解析预先定义好的所述插件清单文件,从所述插件清单文件提供的所述Fragment组件的类名与所述插件包名的对应关系,获得所述Fragment组件所在插件包名。本实施例即采用此种方法。
所述插件清单文件是指存有Fragment组件的类名与其所在的插件包名的映射的文件,该文件的格式有很多种,例如JSON格式、XML格式等,本实施例采用JSON格式的文件储存,以Fragment组件的类名作为key,其所对应的插件包名作为value,例如,插件包1的包名为bundle1,该插件包中包含有类名为firstFragment的Fragment组件1,则插件清单中存在一组key-value键值对,key的值为firstFragment,其所对应的value值为bundle1。
如图2所示,其为本申请的读取并解析插件清单文件的优选技术方案的流程图,具体包括以下步骤:
S102-1:拦截PathClassLoader,替换成预先自定义的类加载器。
所述PathClassLoader是Android系统类加载器,Android系统默认使用该类加载器加载已知类,所述已知类是指已经安装在Android系统的APK的类,而没有安装的APK则不在所述系统类加载器PathClassLoader的查找范围。
所述类加载器是指Java类加载器,其作用是加载类到Java虚拟机中。在使用一个类之前,Java虚拟机(JVM)需要先将该类的字节码文件(.class文件)从磁盘、网络或其他来源加载到内存中,并对字节码进行解析生成对应的Class对象,这就是类加载器的功能。一般来说,Java虚拟机使用Java类的方式如下:Java源程序(.java文件)在经过Java编译器编译之后就被转换成Java字节代码(.class文件);类加载器负责读取Java字节代码,并转换成java.lang.Class类的一个实例;每个这样的实例用来表示一个Java类。通过此实例的newInstance方法就可以创建出该类的一个对象。
就本实施例而言,一方面所述应用程序的类可能在未安装的插件APK中,因此不在所述系统类加载器PathClassLoader的查找范围内;另一方面,Fragment组件不属于Android系统四大标准组件,因此,系统无法从配置文件中找到所述Fragment组件的类所在的插件包;本实施例由于在应用程序中加入了自定义的插件清单文件,相应地,应当设计一个自定义的类加载器,以实现对所述插件清单的读取和解析,进而匹配到目标插件包并进行安装运行。
S102-2:启动所述预先自定义的类加载器;
代理hook技术是Android开发的一项经典技术,其原理是开发者自行创建代理对象,然后把原始对象替换为所述代理对象,那么就可以在这个代理对象中增加自己需要的功能或者对原有功能进行一定的修改。一般来说,代理hook后的方法将比所述原有方法具有更多、更强大的功能。就本实施例而言,采用代理hook技术对系统类加载器进行拦截,进而将其替换成自定义类加载器,在自定义的类加载器中增加对所述插件清单文件的读取和解析功能。
S102-3:所述自定义的类加载器根据所述Fragment组件的类名查找预先定义好的插件清单文件,获得所述Fragment组件所在插件包名。
本步骤在自定义类加载器中完成。具体通过重写findClass方法实现。Android加载类的过程也就是Java加载类的过程,实质上是调用loadClass方法,在loadClass方法中调用findLoadedClass方法来检查该类是否已经被加载过,如果没有就会调用父加载器的loadClass方法,如果父加载器无法加载该类,就调用findClass方法来查找该类。所以所述自定义类加载器继承于系统类加载器PathClassLoader,重写其中的findClass方法,该方法实现以下功能:
读取并解析所述插件清单文件,将所述Fragment组件的类名与解析后的插件清单文件进行匹配,筛选出与所述Fragment组件的类名所对应的插件包名,并输出所述插件包名。
通过上述具体方式,即可实现根据所述Fragment组件的类名,获得其所在的插件包名。
S103:根据所述插件包名安装运行所述插件包。
所述插件包是一个独立的APK安装文件,本实施例中,所述插件包中含有所述Fragment组件,在插件包没有被安装的情况下,其中的各种组件无法被实例化,因此需要安装所述插件包才能成功启动所述Fragment组件,加载到所述应用程序的主APK中。
现有技术下,具有多种场景可以触发插件包的安装过程;可以在Android系统四大组件启动时,也可以在Fragment组件启动时;对于本实施例,是指Fragment组件启动时安装插件包的场景。
安装插件包时主要是执行下述工作:首先,准备插件的类加载器;其次,准备插件包所用资源文件,以保证插件内组件被调用时正常运行。
S104:所述插件包的类加载器加载运行所述Fragment组件。
由于所述插件包已经安装,因此,所述插件包的类加载器能够在所述插件包内查找到Fragment组件的类的位置,进而进行加载运行,被添加在相关界面中。
一般情况下,上述步骤能够正常执行,但不排除存在一些不确定的客观因素影响最终程序的执行,例如,插件APK文件IO异常,磁盘空间不足,系统优化类文件失败等原因导致的Fragment所在插件包安装失败;如果出现此种情况,用户屏幕有可能出现乱码、空白或黑白的情况,影响用户的使用体验。为了提升应用程序的健壮性和灵活扩展性,本申请特别提供了上述方法加载Fragment失败时的补救措施。此种补救措施的核心是,当由于某些原因导致所述Fragment组件经过上述步骤未能成功加载的情况下,应当采取另一种不同的方式呈现所述Fragment组件的内容。
如图3所示,其为本申请的Android插件框架下不同插件间启动Fragment组件的方法第二实施例的流程图。本实施例包含第一实施例的所有步骤,并检测第一实施例中所述Fragment组件是否加载成功,具体包括以下步骤:
S101~S104:已在第一实施例中已详细介绍,在此不再赘述。
S105:检测所述Fragment组件是否加载成功,若否,则进入后续步骤。
在实际执行过程中,很可能出现Fragment组件所在的插件包安装失败,例如,插件APK文件IO异常,磁盘空间不足,系统优化类文件失败等情况导致的插件包安装失败,从而会导致所述Fragment组件加载失败。若Fragment组件加载失败,系统会产生加载失败的信息,从而启动下一步动作。
S201:所述Fragment组件被替换成预先在主APK定义的代理类。
所述代理类是指在开发过程中,预先在主APK中定义的一个Fragment组件的代理类,所述代理类继承自系统Fragment类,同样也是一个Fragment组件;目的是取得所述启动失败的Fragment组件的类名。
所述主APK是指应用程序中起到核心作用的APK,通常是应用程序启动时运行的APK。
S202:对所述代理类执行实例化,通过反射机制在其构造函数中获取所述Fragment组件的类名。
所述实例化,是指用类创建对象的过程,所述构造函数是类的特殊的成员函数。在大多数面向对象的程序设计语言中,类都有一种特殊的成员函数,它的名字和类名相同,没有返回值,不需要用户显式调用,而是在创建对象时自动执行。所述反射机制,是指应用程序在运行时可以访问、检测和修改它本身状态或行为的一种能力。由于事前无法预测是哪个Fragment组件启动失败,因此需要用反射的机制动态获取所述启动失败的Fragment的相关信息。
S203:通过所述Fragment组件的类名,获得对应所述Fragment组件的URL链接。
所述URL链接是指服务器提供的访问特定内容的特定网址,这些内容包括各种类型的文件、数据或者可显示的网页等。通常Fragment组件的数据来自服务器,在应用程序开发时,通过服务器提供的接口获得这些数据并解析,然后加载到Fragment组件的各个部分中,呈现给用户;同时,这些数据也往往用于网页端的开发,以网页的形式与用户进行交互。所述接口一般是以URL链接的形式存在,其数据类型一般也是字符串类型。所述网页端往往会提供URL链接,用户可以通过浏览器客户端访问服务器提供的网页内容。本步骤中所述Fragment组件的URL链接是指含有所述启动失败的Fragment组件内容的网页URL链接。
所述通过所述Fragment组件的类名,获得对应所述Fragment组件的URL链接,通过如下方法中的一种实现:
读取配置文件中Fragment组件的类名与其所对应的URL链接的映射关系,通过Fragment组件的名称映射,获得对应所述Fragment组件的URL链接;或,
将所述Fragment组件的类名传入预先设定好的服务器端,服务器端查询预先设定好的Fragment组件的类名与其所对应的URL链接的映射关系,获得所述Fragment组件的URL链接并返回给客户端;或,
在客户端硬编码中定义Fragment组件的类名与URL链接映射。
第一种方法中Fragment组件的类名与其所对应的URL链接的映射关系储存在配置文件中,当启动Fragment组件失败时,所述代理类会获取所述启动失败的Fragment组件的类名,并在所述代理类加载时执行onCreateView方法,读取所述工程配置文件Fragment降级配置,获得含有所述启动失败的Fragment组件内容的URL链接;
第二种方法中,Fragment组件的类名与其所对应的URL链接的映射关系存储在服务器中,因此,根据Fragment组件的类名查找其所对应的URL链接的工作在服务器端完成,当启动Fragment组件失败时,所述代理类会获取所述启动失败的Fragment组件的类名,并在所述代理类加载时执行onCreateView方法,将所述启动失败的Fragment组件的类名传送至服务器端,服务器端在匹配到含有所述启动失败的Fragment组件内容的URL链接后,将所述含有所述启动失败的Fragment组件内容的URL链接返回给客户端;
第三种方法中所述硬编码是指在开发过程中将Fragment组件的类名与其所对应的URL链接的映射关系以代码的形式储存起来,当启动Fragment组件失败时,所述代理类会获取所述启动失败的Fragment组件的类名,并在所述代理类加载时执行onCreateView方法,在代码内部获取含有所述启动失败的Fragment组件内容的URL链接;
本实施例采用第二种方法,这个方法的优点是,可以随时在服务器端修改Fragment组件的类名与其所对应的URL链接的映射关系而不影响其他部分的正常工作,具有灵活性和便捷性。
S204:实例化系统WebviewFragment组件,将所述URL链接设置进该组件。
所述WebviewFragment组件是Android系统组件,用于在Android应用程序中显示网页界面,将一个URL链接设置进该组件,在该组件运行时会加载显示所述URL链接对应的网页界面。本步骤将步骤S203中所述获得对应所述Fragment组件的URL链接设置进所述WebviewFragment组件,用于使用WebviewFragment组件显示所述启动失败的Fragment组件对应的URL链接的网页内容。
S205:将所述WebviewFragment组件添加到Activity组件中,替换所述代理类;或者,将所述WebviewFragment组件覆盖在所述代理类的上面,并执行所述WebviewFragment组件。
本步骤的目的是将所述带有所述启动失败的Fragment组件对应的URL链接的WebviewFragment组件添加到所述启动失败的Fragment组件本应当添加到的Activity组件当中启动,将所述启动失败的Fragment组件对应的URL链接的网页内容呈现给用户,并与用户交互。所述代理类此时已经没有任何实际意义,因此,无论用所述WebviewFragment组件替换所述代理类,或者是将所述WebviewFragment组件覆盖在所述代理类的上面,只要能达到向用户呈现所述启动失败的Fragment组件对应的URL链接的网页内容,并与用户交互的目的即可。
相对应的,本申请第三实施例提供了一种Android插件框架下不同插件间启动Fragment组件的装置,如图4所示,其为本申请第三实施例提供的Android插件框架下不同插件间启动Fragment组件的装置实施例的示意图。
所述Android插件框架下不同插件间启动Fragment组件的装置,包括接收单元301、匹配单元302、安装单元303、运行单元304。
所述接收单元301,用于接收来自系统的向Activity组件上添加Fragment组件的命令;
所述匹配单元302,用于根据所述接收单元301中Fragment组件的类名,并采用预定的方法,获得其所在的插件包名;
所述安装单元303,用于安装所述匹配单元提供的插件包名的插件包;
所述运行单元304,用于使用所述安装完成的插件包中的类加载器加载运行所述Fragment组件。
优选的,所述Android插件框架下不同插件间启动Fragment组件的装置包括:
启动加载器单元,用于启动预先自定义的类加载器;
查找单元,用于所述启动加载器单元中所述自定义类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名。
优选的,所述Android插件框架下不同插件间启动Fragment组件的装置,所述查找单元中所述启动加载器单元中所述自定义类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名采用如下方式实现:复写所述自定义类加载器中findClass方法,实现对所述预先定义好的插件清单文件的读取;在读取的插件清单文件中,查找所述Fragment组件的类名对应的插件包名。
优选的,所述启动加载器单元启动预先自定义类加载器的过程是通过将代理hook系统类加载器PathClassLoader,替换成自定义类加载器实现启动。
优选的,所述Android插件框架下不同插件间启动Fragment组件的装置,其特征在于,包括硬编码读取单元,用于读取预先在客户端硬编码中定义好的所述Fragment组件的类名与其所在插件包名映射,获得其所在的插件包名。
优选的,所述Android插件框架下不同插件间启动Fragment组件的装置,包括检测单元,用于在所述运行单元加载运行所述安装单元安装完成的所述插件包中所述Fragment组件后,检测所述Fragment组件是否加载成功,若否,则包括:
替换单元,用于将所述Fragment组件替换成预先在主APK定义的代理类;
获取类名单元,用于对所述替换单元提供的所述代理类执行实例化,通过反射机制在其构造函数中获取所述替换单元中所述Fragment组件的类名;
获取URL链接单元,用于通过所述获取类名单元提供的所述Fragment组件的类名,获得对应所述Fragment组件的URL链接;
实例化WebviewFragment单元,用于实例化系统WebviewFragment组件,将所述获取URL链接单元提供的所述URL链接设置进该组件;
代理类替换单元,用于将所述实例化WebviewFragment单元中所述WebviewFragment组件添加到Activity组件中,替换所述代理类;或者,
覆盖单元,将所述实例化WebviewFragment单元中所述WebviewFragment组件覆盖在所述代理类的上面,并执行所述WebviewFragment组件。
本申请同时提供一种电子设备,该电子设备支持Android系统,包括:处理器;以及存储器;所述存储器用于存储一种Android插件框架下不同插件间启动Fragment组件的程序,该设备通电并通过所述处理器运行所述Android插件框架下不同插件间启动Fragment组件的程序后,执行下述步骤:
系统接收到向Activity组件上添加Fragment组件的命令;
根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名;
根据所述插件包名安装运行所述插件包;
所述插件包的类加载器加载运行所述Fragment组件。
本申请虽然以较佳实施例公开如上,但其并不是用来限定本申请,任何本领域技术人员在不脱离本申请的精神和范围内,都可以做出可能的变动和修改,因此本申请的保护范围应当以本申请权利要求所界定的范围为准。
Claims (14)
1.一种Android插件框架下不同插件间启动Fragment组件的方法,其特征在于,包括:
系统接收到向Activity组件上添加Fragment组件的命令;
根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名;
根据所述插件包名安装运行所述插件包;
使用所述插件包的类加载器加载运行所述Fragment组件。
2.根据权利要求1所述的方法,其特征在于,
所述根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名的步骤,所述预定的方法为如下方法:
启动预先自定义的类加载器;
所述自定义的类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名。
3.根据权利要求2所述的方法,其特征在于,
所述自定义类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名采用如下方式实现:复写所述自定义类加载器中findClass方法,实现对所述预先定义好的插件清单文件的读取;在读取的插件清单文件中,查找所述Fragment组件的类名对应的插件包名。
4.根据权利要求2所述的方法,其特征在于,
所述启动预先自定义类加载器的过程是通过将代理hook系统类加载器PathClassLoader,替换成自定义类加载器实现启动的。
5.根据权利要求1所述的方法,其特征在于,
所述根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名的步骤,所述预定的方法为如下方法:
读取预先在客户端硬编码中定义好的所述Fragment组件的类名与其所在插件包名映射,获得其所在的插件包名。
6.根据权利要求1所述的方法,其特征在于,
在所述插件包的类加载器加载运行所述Fragment组件的步骤之后,检测所述Fragment组件是否加载成功,若否,则执行以下步骤:
所述Fragment组件被替换成预先在主APK定义的代理类;
对所述代理类执行实例化,通过反射机制在其构造函数中获取所述Fragment组件的类名;
通过所述Fragment组件的类名,获得对应所述Fragment组件的URL链接;
实例化系统WebviewFragment组件,将所述URL链接设置进该组件;
将所述WebviewFragment组件添加到Activity组件中,替换所述代理类;或者,
将所述WebviewFragment组件覆盖在所述代理类的上面,并执行所述WebviewFragment组件。
7.根据权利要求6所述的方法,其特征在于,
所述通过所述Fragment组件的类名,获得对应所述Fragment组件的URL链接,通过如下方法中的一种实现:
读取配置文件中Fragment组件的类名与其所对应的URL链接的映射关系,通过Fragment组件的名称映射,获得对应所述Fragment组件的URL链接;或,将所述Fragment组件的类名传入预先设定好的服务器端,获得服务器端输出的对应所述Fragment组件的URL链接;或,
读取预先在客户端硬编码中定义好的Fragment组件的类名与URL链接映射,获得对应所述Fragment组件的URL链接。
8.一种Android插件框架下不同插件间启动Fragment组件的装置,其特征在于,包括:
接收单元,用于接收来自系统的向Activity组件上添加Fragment组件的命令;
匹配单元,用于根据所述接收单元中Fragment组件的类名,并采用预定的方法,获得其所在的插件包名;
安装单元,用于安装所述匹配单元提供的插件包名的插件包;
运行单元,用于使用所述安装完成的插件包中的类加载器加载运行所述Fragment组件。
9.根据权利要求8所述的装置,其特征在于,包括:
启动加载器单元,用于启动预先自定义的类加载器;
查找单元,用于所述启动加载器单元中所述自定义类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名。
10.根据权利要求9所述的装置,其特征在于,
所述查找单元中所述启动加载器单元中所述自定义类加载器根据所述Fragment组件的类名查找并解析预先定义好的插件清单文件,获得所述Fragment组件所在插件包名采用如下方式实现:复写所述自定义类加载器中findClass方法,实现对所述预先定义好的插件清单文件的读取;在读取的插件清单文件中,查找所述Fragment组件的类名对应的插件包名。
11.根据权利要求9所述的装置,其特征在于,
所述启动加载器单元启动预先自定义类加载器的过程是通过将代理hook系统类加载器PathClassLoader,替换成自定义类加载器实现启动。
12.根据权利要求8所述的装置,其特征在于,
包括硬编码读取单元,用于读取预先在客户端硬编码中定义好的所述Fragment组件的类名与其所在插件包名映射,获得其所在的插件包名。
13.根据权利要求8所述的装置,其特征在于,
包括检测单元,用于在所述运行单元加载运行所述安装单元安装完成的所述插件包中所述Fragment组件后,检测所述Fragment组件是否加载成功,若否,则包括:
替换单元,用于将所述Fragment组件被替换成预先在主APK定义的代理类;
获取类名单元,用于对所述替换单元提供的所述代理类执行实例化,通过反射机制在其构造函数中获取所述替换单元中所述Fragment组件的类名;
获取URL链接单元,用于通过所述获取类名单元提供的所述Fragment组件的类名,获得对应所述Fragment组件的URL链接;
实例化WebviewFragment单元,用于实例化系统WebviewFragment组件,将所述获取URL链接单元提供的所述URL链接设置进该组件;
代理类替换单元,用于将所述实例化WebviewFragment单元中所述WebviewFragment组件添加到Activity组件中,替换所述代理类;或者,
覆盖单元,用于将所述实例化WebviewFragment单元中所述WebviewFragment组件覆盖在所述代理类的上面,并执行所述WebviewFragment组件。
14.一种电子设备,其特征在于,该电子设备支持Android系统,包括:
处理器;以及
存储器,用于存储一种Android插件框架下不同插件间启动Fragment组件的程序,该设备通电并通过所述处理器运行所述Android插件框架下不同插件间启动Fragment组件的程序后,执行下述步骤:
系统接收到向Activity组件上添加Fragment组件的命令;
根据所述Fragment组件的类名,采用预定的方法,获得其所在的插件包名;
根据所述插件包名安装运行所述插件包;
所述插件包的类加载器加载运行所述Fragment组件。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201611155111.5A CN108228266B (zh) | 2016-12-14 | 2016-12-14 | 一种Android插件框架下不同插件间启动Fragment组件的方法和装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201611155111.5A CN108228266B (zh) | 2016-12-14 | 2016-12-14 | 一种Android插件框架下不同插件间启动Fragment组件的方法和装置 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN108228266A true CN108228266A (zh) | 2018-06-29 |
CN108228266B CN108228266B (zh) | 2021-08-10 |
Family
ID=62651132
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201611155111.5A Active CN108228266B (zh) | 2016-12-14 | 2016-12-14 | 一种Android插件框架下不同插件间启动Fragment组件的方法和装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN108228266B (zh) |
Cited By (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110413913A (zh) * | 2019-07-04 | 2019-11-05 | 北京字节跳动网络技术有限公司 | 一种页面刷新方法、装置、终端及存储介质 |
CN111813476A (zh) * | 2020-06-30 | 2020-10-23 | 中天掌金(北京)科技有限公司 | 一种基于安卓负一屏的手机银行应用方法 |
CN114528048A (zh) * | 2022-02-18 | 2022-05-24 | Oppo广东移动通信有限公司 | 应用执行方法、应用执行架构、电子设备及存储介质 |
Citations (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101763262A (zh) * | 2009-10-13 | 2010-06-30 | 武汉大学 | 一种基于模型驱动的地理信息服务组合设计器生成方法 |
CN103702224A (zh) * | 2013-12-27 | 2014-04-02 | 乐视致新电子科技(天津)有限公司 | 电视机及该电视机上显示存储设备的方法和装置 |
CN103744669A (zh) * | 2013-12-26 | 2014-04-23 | 世纪龙信息网络有限责任公司 | 安卓系统Activity插件的创建、调用方法及系统 |
US20140136664A1 (en) * | 2012-10-02 | 2014-05-15 | Nextbit Systems Inc. | Resource based mobile device application streaming |
CN103927180A (zh) * | 2014-04-21 | 2014-07-16 | 广州市久邦数码科技有限公司 | 一种基于安卓系统的功能插件的实现方法及其系统 |
CN104731625A (zh) * | 2015-03-27 | 2015-06-24 | 北京奇虎科技有限公司 | 一种加载插件的方法、装置和移动终端 |
CN105224310A (zh) * | 2015-09-06 | 2016-01-06 | 浪潮软件股份有限公司 | 一种基于android多fragment提升hybrid应用体验的方法 |
CN105893061A (zh) * | 2016-06-12 | 2016-08-24 | 杭州勒芒科技有限公司 | 应用程序开发方法及系统 |
-
2016
- 2016-12-14 CN CN201611155111.5A patent/CN108228266B/zh active Active
Patent Citations (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101763262A (zh) * | 2009-10-13 | 2010-06-30 | 武汉大学 | 一种基于模型驱动的地理信息服务组合设计器生成方法 |
US20140136664A1 (en) * | 2012-10-02 | 2014-05-15 | Nextbit Systems Inc. | Resource based mobile device application streaming |
CN103744669A (zh) * | 2013-12-26 | 2014-04-23 | 世纪龙信息网络有限责任公司 | 安卓系统Activity插件的创建、调用方法及系统 |
CN103702224A (zh) * | 2013-12-27 | 2014-04-02 | 乐视致新电子科技(天津)有限公司 | 电视机及该电视机上显示存储设备的方法和装置 |
CN103927180A (zh) * | 2014-04-21 | 2014-07-16 | 广州市久邦数码科技有限公司 | 一种基于安卓系统的功能插件的实现方法及其系统 |
CN104731625A (zh) * | 2015-03-27 | 2015-06-24 | 北京奇虎科技有限公司 | 一种加载插件的方法、装置和移动终端 |
CN105224310A (zh) * | 2015-09-06 | 2016-01-06 | 浪潮软件股份有限公司 | 一种基于android多fragment提升hybrid应用体验的方法 |
CN105893061A (zh) * | 2016-06-12 | 2016-08-24 | 杭州勒芒科技有限公司 | 应用程序开发方法及系统 |
Non-Patent Citations (1)
Title |
---|
CXMSCB: "安卓之插件化开发使用DexClassLoader&AssetManager实现功能插件化", 《HTTPS://BLOG.CSDN.NET/CXMSCB/ARTICLE/DETAILS/52454914》 * |
Cited By (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110413913A (zh) * | 2019-07-04 | 2019-11-05 | 北京字节跳动网络技术有限公司 | 一种页面刷新方法、装置、终端及存储介质 |
CN111813476A (zh) * | 2020-06-30 | 2020-10-23 | 中天掌金(北京)科技有限公司 | 一种基于安卓负一屏的手机银行应用方法 |
CN114528048A (zh) * | 2022-02-18 | 2022-05-24 | Oppo广东移动通信有限公司 | 应用执行方法、应用执行架构、电子设备及存储介质 |
Also Published As
Publication number | Publication date |
---|---|
CN108228266B (zh) | 2021-08-10 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US9779111B2 (en) | Method and system for configuration of virtualized software applications | |
US9864600B2 (en) | Method and system for virtualization of software applications | |
US9588752B2 (en) | Performing unattended software installation | |
CN101771762B (zh) | 业务系统中业务动态加载系统及方法 | |
US7886035B2 (en) | Profile service based deployment configuration | |
US8863108B2 (en) | Finding out if software will run on an operating system without installing that software | |
US8499294B2 (en) | Persisting the changes for managed components in an application server | |
US10684846B2 (en) | Using semantic annotations to control compatibility behaviors | |
US20150220308A1 (en) | Model-based development | |
US20110078672A1 (en) | Classloading Technique for an Application Server that Provides Dependency Enforcement | |
CN110187910B (zh) | 一种热更新方法、装置、设备及计算机可读存储介质 | |
US8887122B2 (en) | Find and track information of interface usage of software libraries by other software | |
US20230259358A1 (en) | Documentation enforcement during compilation | |
CN108228266A (zh) | 一种Android插件框架下不同插件间启动Fragment组件的方法和装置 | |
US8407678B2 (en) | Method of array interception using data-flow analysis | |
US8516448B2 (en) | Identifying interpreted programs through class loading sequences | |
CN112099880A (zh) | 场景驱动的应用程序约减方法和系统 | |
US9841982B2 (en) | Locating import class files at alternate locations than specified in classpath information | |
US11366657B2 (en) | Inferring code deprecation from module deprecation | |
US10394610B2 (en) | Managing split packages in a module system | |
CN114816445A (zh) | 系统平台架构、函数发布方法及装置、平台及存储介质 | |
US10346225B2 (en) | Synthesized modules for module renaming | |
CN117436080A (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 | ||
GR01 | Patent grant | ||
GR01 | Patent grant |