背景技术
Android是一种以Linux为基础的开放源代码操作系统,主要使用于便携设备。2012年2月数据,Android占据全球智能手机操作系统市场52.5%的份额,中国市场占有率为68.4%。
Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。Eclipse 还包括插件开发环境(Plug-in Development Environment,PDE),这个组件主要针对希望扩展 Eclipse 的软件开发人员,因为它允许他们构建与 Eclipse 环境无缝集成的工具。由于 Eclipse 中的每样东西都是插件,对于给 Eclipse 提供插件,以及给用户提供一致和统一的集成开发环境而言,所有工具开发人员都具有同等的发挥场所。
Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaSE, JavaEE, JavaME)的总称。
模块化是指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程,有多种属性,分别反映其内部特性。模块化是另一种处理复杂系统分解为更好的可管理模块的方式。模块化用来分割,组织和打包软件。每个模块完成一个特定的子功能,所有的模块按某种方法组装起来,成为一个整体,完成整个系统所要求的功能。在系统的结构中,模块是可组合、分解和更换的单元。模块化是一种处理复杂系统分解成为更好的可管理模块的方式。它可以通过在不同组件设定不同的功能,把一个问题分解成多个小的独立、互相作用的组件,来处理复杂、大型的软件。
一般的基于Android开发都是所有源代码放在一起,相互依赖,不能独立出来只注重开发某一个特定的功能,独立维护版本,这给开发和测试都带来了一定的麻烦,同时由于代码局限于特定的应用内部,不能在多个项目中达到重用的目的,开发效率会变得很低。
同时,如果某一个功能出现问题,会造成整个应用的不可用,会大大影响整个项目的开发进度,所有的其它功能都必须等待某一个功能完成才能继续开发。同时在针对不同问题的解决方案上,模块化有无可比拟的优势。
目前Android开发的Eclipse插件ADT(Android Develop Toolkit)并不包含依赖管理,它仅仅能依赖其它第三方的纯Java Jar包,但是Android的应用程序是要包含资源文件以及Activity的定义文件的,没有资源和Activity定义,这个Android的模块是不可用的。这就为Android的模块化开发带来了一大难题,因为即便你把这些资源文件和配置文件打包在一个Jar包中,ADT也是认不出来的,更不会对它进行编译和打包处理。
Eclipse的插件特性决定着可以控制ADT的编译过程,从而在它编译之前,对封装了资源和配置文件的Jar包进行处理,使ADT能够对它进行整合,编译以及打包。
同时由于默认的导出Jar文件并不包含Android模块文件的导出,所以还需要依靠Eclipse的插件特性,使其能够打包为想要的包含资源和配置的Jar文件。
最后,在移除某一个Android模块时,还需要对整个项目进行清理工作,使它变得和模块加入前一样。
依靠这样的特性,就可以达到像其它Java程序开发一样开发Android的应用程序,对于Android的开发者以及公司的生产率提高,极具重要的意义。
发明内容
鉴于现有技术存在的不足,在Android项目开发中,不可避免地要用到模块化开发,分小组开发不同的模块,最后整合成一个应用,并且最好能随意地卸载一个模块,但是当前的Android开发插件ADT(Android Develop Toolkit)无法满足模块化开发的基本要求,无法进行jar包的独立导出和自动集成。
虽然ADT可以采用引用项目的方式执行,但是更多的情况下,需要编译好的模块文件,主项目可以通过加载和移除这些模块文件,来增加或者删除某个模块的功能。
本发明解决的问题:本发明可以使Android程序模块单独编译为jar包的形式,其它 Android程序可以解析这个jar包,把这个模块的功能加入到新的Android程序中。并且可以通过移除jar包来移除某个组件的功能。
本发明采用的技术方案为:本发明基本Eclipse的插件特性和Android的ADT插件特征,提出了Android的模块化开发方法,并且给出了Android模块化的开发方案。技术方案分为3部分,分别解决在模块化开发过程中的导出模块、导入模块、移除模块的问题解决方案。导入和移除操作是监控项目的modules文件夹实现的,如果这个文件夹中加入了新文件并且以.jar结尾,默认为它是模块文件,启动导入过程,如果从这个文件夹中移除了文件,并且以.jar结尾,启动移除过程,如果是替换文件,则分别先后启动移除和导入过程。
一种Android模块化开发方法,它包括导出模块步骤、导入模块步骤、移除模块步骤,导入和移除操作是监控项目的modules文件夹实现的,如果这个文件夹中加入了新文件并且以.jar结尾,默认为它是模块文件,启动导入过程,如果从这个文件夹中移除了文件,并且以.jar结尾,启动移除过程,如果是替换文件,则分别先后启动移除和导入过程。
所述导出模块步骤,
步骤1.1 当Android项目的isLibrary属性选中时,Android编译器生成的R文件中的字段将是public static类型,对于这种的引用,在编译期是不会编译为常量值的,当资源索引发生变化时,引用也不会受到影响;
步骤1.2 将Res目录打包进Jar文件中;
步骤1.3 在模块的Src目录下建立META-INF文件夹,在文件夹内建立activity文件,文件内容是所有本模块开放的Activity,每行书写一个全路径的Activity类名。
所述导入模块步骤,
步骤2.1 将模块Jar包中的资源文件复制到项目目录下,将导入模块Jar中的Class文件重新打包为Jar,命名方式为Module_原文件名,放在项目根目录下的.am文件夹中,并将新的纯类库Jar包加入到项目的引用中;
步骤2.2 模块与项目的包命令必须相同;
步骤2.3 读取Jar包中 META-INF/activity文件,将Activity分别注册到AndroidManifest.xml中;
步骤2.4 在复制资源文件的时候,如果原先项目中已经存在的资源,不做替换;
步骤2.5 对于res/values/strings.xml中定义的内容,采用合并的方式,对于原有文件中已经在在的item,不做覆盖。
所述移除模块步骤,
步骤3.1 在导入模块的过程中,加入日志记录,生成日志文件放在.am文件夹中,命名为Module_模块原文件名.cfg;
步骤3.2 对于导入的资源,日志记录为res:资源路径;
步骤3.3 对于导入的Activity,日志记录为activity:类路径;
步骤3.4 对于合并的strings.xml内容,日志记录为 strings:行内容;
步骤3.5 移除的时候,逐行读取日志记录,移除导入的资源,最后删除.am文件夹下的Jar包和日志文件、原模块Jar包以及类路径的引用。
本发明的有益效果为:提高Android开发的灵活性和生产效率,将系统分割为更高内聚、低耦合的不同模块,减少了程序的复杂性,提高了系统的稳定性和扩展性。通过独立的打包,使模块的可重用性大大提高,减少了开发中的重复工作。
具体实施方式
以下结合附图和具体实施例对本发明作进一步详细说明。
【实施例1】导出模块。如图1、图2、图3所示。
1. Android编译器默认生成的R.class文件中的字段是public static final类型的,对于R文件的引用(例如:R.layout.main)都会被编译为常量值(例如:0x7f020000),但是一旦作为模块,加入到其它项目中,资源的索引值(即R文件)是会改变的(例如变成了:0x7f060018),这意味着,原先对于资源的引用(0x7f020000)将会找不到这个资源文件,由此会发生错误。
2. Android编译器默认不会打包资源文件。
3. 导出模块需要告知其它项目,它一共有多少可用的Activity,以便其它项目在得到这个模块后,可以将Activity注册到AndroidManifest.xml。
解决方案
1. 当Android项目的isLibrary属性(项目->右击->Properties->Android->IsLibrary)选中时,Android编译器生成的R文件中的字段将是public static类型(非final),对于这种的引用,在编译期是不会编译为常量值的(例如:R.layout.main依然是R.layout.main,而不是0x7f020000),这样,当资源索引发生变化时,引用也不会受到影响。
2. 将Res目录打包进Jar文件中。
3. 在模块的Src目录下建立META-INF文件夹,在文件夹内建立activity文件,文件内容是所有本模块开放的Activity,每行书写一个全路径的Activity类名(如:jevon.view.TestActivity)。
1.1. 导出模块
在Eclipse的Export中Android的类别下添加Android Module选项,通过这个选项来导出Module Jar,如图6所示。
Module Jar包含了Config,Resources,Classes三个部分,以Jar包的形式打包,文件夹结构如图7所示。
1.1.1. Config
Config对应的配置放在模块的Src目录下的META-INF文件夹下,其中:
activity文件中包含了对模块所有Activity的路径,每行表示一个Acitivity,如:
Test.sino-device.TestActivity.。
1.1.2. Classes
Classes包含本模块所有的经过编译的Java Class文件。
1.1.3. Resources
Resources包含了本模块里面Res目录下的所有文件。
【实施例2】导入模块。如图4所示。
1. Android的编译器在编译期不会检测jar包中的资源文件。这就意味着,即便把资源文件打包在模块Jar文件中,Android编译器还是不会将它添加到资源索引文件R中。
2. Android的构建器在生成期会检测jar包的资源文件。将Android项目导出为APK的时候,构建器会检测Jar包中的资源文件,这意味着,如果将模块Jar文件中的资源文件导出到项目中,那么会造成重复(Jar文件中有一份,项目目录中也有一份),这个重复会造成程序的运行期错误。
3. 只有Android项目的package参数指定的目录生成的R文件,才会包含所有文件的索引。这意味着如果旧模块的package参数与新项目的package参数不同(如一个是mod.jevon,一个是prj.jevon),那么编译器只会生成prj.jevon.R。这样造成的后果就是原先对mod.jevon.R的引用会找不到。生成的时候会报ClassNotFound错误。
4. 模块的Activity注册。在没有Activity注册的情况下,模块是运行不起来的。
解决方案
1. 将模块Jar包中的资源文件复制到项目目录下(使Android编译器可以将资源添加到R文件中),将模块Jar中的Class文件重新打包为Jar,命名方式为Module_原文件名,放在项目根目录下的.am文件夹中,并将新的纯类库Jar包加入到项目的引用中(修改项目的.classpath文件,避免模块资源的重复引用)。
2. 模块与项目的包命令必须相同,建议作为公司项目的话,统一使用公司的域名,如:com.sinodevice。
3. 读取Jar包中 META-INF/activity文件,将Activity分别注册到AndroidManifest.xml中。
4. 在复制资源文件的时候,如果原先项目中已经存在的资源,不做替换。
5. 对于res/values/strings.xml中定义的内容,采用合并的方式,对于原有文件中已经在在的item,不做覆盖。
1.2. 导入模块
将Module Jar放在Android项目根目录的modules文件夹中,插件会解析Module Jar,然后分别读取Config,Classes,以及Resources。
1、在项目根目录建立.am文件夹。
2、将Module Jar里面解析出来的Classes,重新打包为Jar,命令为Module_{原Module Jar名称}.jar,将该Jar包放入.am文件夹下,同时将这个新Jar添加到项目的BuildPath。
3、在.am文件夹下建立LogFile:Module_{原Module Jar名称}.jar.cfg。
4、读取Module Jar 下META-INF文件夹中的activity文件,将其中的Activity注册到项目的AndroidManifest.xml文件中,并将这些Activity记录进LogFile文件中。记录以activity:开头,如:activity:ds.sinodevice.TestActivity。
5、读取Module Jar下的Res文件夹下的文件,将其中的文件复制到项目的Res目录下,并将复制的文件记录到LogFile中。记录以res:开头,如:res:res/drawable/logo.png。
6、将res/values/strings.xml文件进行合并。将合并的属性值也记录到LogFile中。记录以strings:开头,如:strings:<string name="close">Close</string>。
【实施例3】移除模块。如图5所示。
1、需要移除导入模块时候的一些资源(资源,类库,配置等等)。
2、需要移除类路径对类库的引用。
解决方案
1、在导入模块的过程中,加入日志记录,生成日志文件放在.am文件夹中,命名为Module_模块原文件名.cfg。
2、对于导入的资源,日志记录为res:资源路径,如:res:res/layout/main.xml。
3、对于导入的Activity,日志记录为activity:类路径,如:activity:com.sinodevice.TestActivity。
4、对于合并的strings.xml内容,日志记录为 strings:行内容,如:strings: <string name="send_button">Send</string>。
5、移除的时候,逐行读取日志记录,移除导入的资源,最后删除.am文件夹下的Jar包和日志文件、原模块Jar包以及类路径的引用。
1.3. 移除模块
1、读取LogFile中的Activity记录,从AndroidManifest.xml中移除。
2、读取LogFile中的Resources记录,从Res文件夹中移除。
3、读取LogFile中的合并属性记录,从strings.xml文件中移除。
4、从.am文件夹中移除Module_{原Module名称}.jar文件。
5、移除LogFile文件。
6、从项目BuildPath中移除对模块Jar的引用。
附加说明
1、需要打开Eclipse的文件自动刷新功能,如图8。
2、模块项目必须是Android Library项目,如图9。
3、请注意,模块项目生成的R文件,里面声明的类型必须不为final,否则,请将项目设置为Library后,删除R文件,eclipse会自动生成新文件。
虽然本发明已以较佳实施例公开如上,但实施例和附图并不是用来限定本发明的。在不脱离本发明之精神和范围内,所做的任何等效变化或润饰,同样属于本发明之保护范围。因此本发明的保护范围应当以本申请的权利要求所界定的内容为标准。