使用ant及IDE配置文件进行Android项目初步的标准化,规范化构建

最近一段时间,随着公司业务规模的扩大,很多移动端Android项目一起上马,同时引进了大量开发人员. 开发人员水平良莠不齐,开发习惯也各不相同. 因为项目时间紧迫,所以对各种<<代码规范>>和公司研发部的<<项目规范>>都执行的不到位,造成项目沟通,维护和后期运营很大的成本浪费. 研发阶段的代码规范问题不再多说,有很多成熟的自动化检测产品,大部分研发人员也轻车熟路. 今天以我们公司的<<Android项目开发规范>>为例,来说一下项目的自动化,标准化构建及如何简洁的实施,说一下思路, 抛砖引玉.   

公司的<<Android项目开发规范>>一共8页,两千多字.如下:

  1. Java代码开发规范(变量命名,方法的命名,包命名,类和接口命名)
  2. res/layout

    文件夹命名规范:

    res/layout中文件命名规范:
    1. 一个activity对应一个主layout.
    2. 名称为"activity_activity名称.xml".  例如LoginActivity.java对应activity_login.xml
    3. 子页面以其主要功能,继续向下细化.如activity_login_dialog.xml
  3. res/drawable

    文件命名规范:

    res/drawable中文件命名规范: 
    1. 小写字母和下划线“_”组合命名.
    2. 图片如果有点击效果则必须以_f结尾. 如btn_login.png对应btn_login_f.png
    3. 其他命名规则按照设计部内部习惯,自行定义.
    4. 开发人员创建的selector文件命名规则如下"select_图片名. 如btn_login.png对应select_btn_login.png
  4. xml规范
    1. id全部以字母和下划线“_”组合命名.小写字母开头.
    2. 规则为"所属activity名称_控件类型_功能". 如登录界面的注册按钮对应login_btn_reg. 控件类型说明:button对应btntextView对应txtListView对应list....
    3. 字符串先在Strng.xml中注册再调用
    4. dp,sp代替pix
  5. 类注释: 
    • 所有的类文件开头、必须要有类的主要作用的简单说明
    • 类创建日期
    • 作者信息
    • 版本改动,更新内容,更新人
  6. 方法注释 
    • 类该方法作用是什么?
    • @param 各个参数说明
    • 异常处理。@throws 
    • @return 方法返回值、代表的意义
  7. 使用增强的for循环
  8. 删除未用到的import引用
  9. 为if/while/for/do增加大括号
  10. 移除所有未使用的变量,方法,局部变量
  11. 移除所有无意义的类型强转
  12. 缩进:不允许使用Tab进行缩进,使用空格进行缩进,推荐缩进为2空格。
  13. 空行
    • 空行将逻辑相关的代码段分隔开,以提高可读性。
    • 一个源文件的两个片段(section)之间
    • 类声明和接口声明之间
    • 两个方法之间 
    • 方法内的局部变量和方法的第一条语句之间
    • 一个方法内的两个逻辑段之间,用以提高可读性
  14. ..................

每个入职的开发人员都要仔细研读,项目开发过程中要严格遵守, 所有代码每周由团队负责人审核,查看是否遵循了规范.从总体效果上来说此规范带来的效益还是很高,即便是新手其文件结构及代码风格都不错, 代码的修改,二次开发,修复bug,人员交接等成本都比较低.  但是开发人员在开发过程中,要注意的条条框框太多,代码频繁被打回,各种前置要求导致开发成本提高,习惯培养也不是一两天可以形成......  规范意味着规则,规则意味着可以配置化,代码化,所以我们通过了一些优化步骤,把此规范简化成了以下三条: 

  1. 导入企业IDE通用配置文件
  2. 项目创建后,使用企业AndroidProjectBuild.xml的初始化功能来初始化项目.(自动创建文件,目录,增加配置等)
  3. 项目后期,使用企业AndroidProjectBuild.xml的构建功能来重构项目.(自动整理资源,优化项目等)
STEP1: 导入企业IDE通用配置文件

本文结尾提供了三个配置文件的下载,已针对Android项目做了规范化处理,各位也可根据自己的需求,新增或修改配置.导入步骤:Eclipse工具栏上选择Window -> Preferences -> Java -> Code Style ->import导入对应的配置文件->edit可根据自己需求,进行二次编辑.  所有开发人员配置完成后,写出的代码从风格上来说就像是一个人.在代码同步时也可以避免不少冲突,更新问题.更重要的是不用再一条一条去看编码规范了, 一个快捷键搞定.



coco_cleanUp.xml: 清理代码功能,在java代码和xml文件中,按Alt+shift+S选择Cleanup. 会自动完成以下工作:

  • 为if/else,while等控制语句,增加{}. 
  • 代码中的for循环会自动修改为增强型for循环.
  • 删除所有没用到的imports,私有变量,私有方法,私有构造方法,局部变量
  • 所有变量定义,都会被整理置于类顶部,并排序.
  • 无意义的类型强转都会取消.
  • 忘记添加的'@Override',@Deprecated' 会自动添加.
  • 会自动导入用到的类,相当于Ctrl+shift+O(取决于Organize imports中的配置)
  • ...................

coco_codeFormat.xml: 格式化代码功能,在java代码和xml文件中,按Ctrl+shift+F. 会自动完成以下工作:

  • 删除空行
  • 方法之间增加换行
  • 每个变量声明独占一行,变量名是否左对齐
  • 可定义每行的最大长度
  • 定义代码缩进风格,比如空格缩进,tab缩进,空格缩进数量,case,switch,if,for等语句缩进风格.
  • 变量,数组,方法等各元素之间间距.
  • 注释的风格,一行多长,是否左对齐,是否换行等.
  • .......................

coco_codetemplates.xml: 代码模板. 会自动完成以下工作:

  • 创建类时,自动添加类版本,创建时间,作者,类名,版权.
  • 选中类,变量,方法按下Alt+Shift+J会自动添加对应注释.
  • 可自行编辑注释模板.
STEP2:使用ant初始化和重构项目 AndroidProjectBuild.xml

上面的配置文件解决了编码风格,注释等问题,但是对文件操作, 图片和资源等命名问题并未涉及. 我们使用ant来完成这部分工作. 以这两天写的<<android项目构建xml>>部分有代表性的代码为例,看下思路.
<?xml version="1.0" encoding="UTF-8"?>
<!-- V1.3 作者fay,Android项目构建文件,ant build文件,适用于架构部UML生成的Android项目,在项目创建完成后初始化使用,
完成功能有
1.(构建功能)为所有类添加标准化注释
2.(初始化功能)自动生成部分XML布局文件
3.(构建功能)自动抽取布局文件中的所有字符串,并在String.xml中注册
4.(构建功能)自动修改布局文件中id命名,并更新项目
5.(初始化功能)自动创建图片的selector文件
6.(初始化功能)actvity在Manifest中注册
7.名为reduce的target不会自动执行,此任务将删除drawable中所有未使用到的图片
8.名为autoFormat的target不会自动执行,此任务将以公司的cleanUp.xml,codeFormat.xml两个配置全盘格式化当前项目代码包括src下的全部文件,layout下的全部文件.
........
-->
<project name="buildAndroidProject" default="searchActivity">
    <property name="path_layout" value="res/layout/" />
    <property name="path_src" value="src" />
    <taskdef name="foreach" classname="net.sf.antcontrib.logic.ForEach" classpath="ant-contrib-1.0b3.jar" />
    <!--判断activity对应的布局XML文件是否已生成过-->
    <target name="detectFile">
        <condition property="fileIsExists">
            <and>
                <available file="res/layout/activity_*.xml" />
            </and>
        </condition>
    </target>
    <!--查找到所有Activity并形成列表-->
    <target name="searchActivity" depends="detectFile" unless="fileIsExists">
        <fileset id="activitysPath" dir="${path_src}">
            <include name="**/*Activity*" />
        </fileset>
        <pathconvert property="activityNameList" refid="activitysPath">
            <mapper>
                <chainedmapper>
                    <flattenmapper />
                    <globmapper casesensitive="no" from="*.java" to="*.xml" /><!--把后缀修改为xml-->
                    <scriptmapper language="javascript"><!--Activity名称转换为小写-->
                        self.addMappedName(source.toLowerCase());
                    </scriptmapper>
                    <filtermapper>
                        <replacestring from="activity" to="" />
                    </filtermapper>
                </chainedmapper>
            </mapper>
        </pathconvert>
        <fileset id="activityPathListID" dir="${path_src}">
            <include name="**/*Activity*" />
        </fileset>
        <pathconvert property="activityPathList" refid="activityPathListID">
            <mapper>
                <chainedmapper><!--去目录-->
                    <regexpmapper from="[\/\\]?src[\/\\](.+).java" to="\1" />
                    <packagemapper from="*" to="*" />
                </chainedmapper>
            </mapper>
        </pathconvert>
        <foreach delimiter=";" list="${activityNameList}" param="activityName" target="createLayout" />
        <foreach delimiter=";" list="${activityPathList}" param="activityPath" target="insertMainFest" />
        <antcall target="searchSelect" />
    </target>
    <!--为每个Activity创建对应的布局文件-->
    <target name="createLayout">
        <touch file="${path_layout}activity_${activityName}" />
        <echo file="${path_layout}activity_${activityName}"
            message="<?xml version='1.0' encoding='utf-8'?>
<RelativeLayout xmlns:android='http://schemas.android.com/apk/res/android'
    android:layout_width='match_parent'
    android:layout_height='match_parent' >
</RelativeLayout>" />
    </target>
    <!--为每个Activity注册-->
    <target name="insertMainFest">
        <replace file="AndroidManifest.xml" token="</application>"
            value="<activity
            android:name='${activityPath}'
            android:configChanges='keyboardHidden|screenSize'
            android:label='labelName'/></application>" />
    </target>
    
    <!--遍历所有图片,筛选出需要自动生成selector的图片-->
    <target name="searchSelect">
        <fileset id="selectImgNameID" dir="res">
            <include name="**/*_f*" />
        </fileset>
        <pathconvert property="selectImgNames" refid="selectImgNameID">
            <mapper>
                <chainedmapper>
                    <flattenmapper />
                    <regexpmapper from="(\S*)_f" to="\1" />
                </chainedmapper>
            </mapper>
        </pathconvert>
        <foreach delimiter=";" list="${selectImgNames}" param="selectImgList" target="createSelect" />
    </target>
    <!-- 自动生成selector -->
    <target name="createSelect">
        <touch file="res/drawable/select_${selectImgList}.xml" />
        <echo file="res/drawable/select_${selectImgList}.xml"
            message="<?xml version='1.0' encoding='utf-8'?>
<selector xmlns:android='http://schemas.android.com/apk/res/android'>

    <item android:drawable='@drawable/${selectImgList}_f' android:state_pressed='true'></item>
    <item android:drawable='@drawable/${selectImgList}' android:state_pressed='false'></item>
    <item android:drawable='@drawable/${selectImgList}'/>

</selector>" />
    </target>.........
</project>

这个XML用了近两天时间写完, 可自动实施<<Android项目开发规范>>中三到四页的规则, 取消了开发人员大量的重复性工作,基本上5秒内完成开发人员需要数个小时的工作. 对于项目多,开发人员多,水平参差不齐的状况,比较适用.  使现在公司研发团队整体效率大大提高,消耗在代码审查,规范实施上的成本低了太多.  本文的思路其实跟做产品的思路有些类似,  不要给用户太多的文档,太多的规范,不要告诉用户你必须怎么做. 而只要跟用户说: 点这个按钮,OK,这就是你想要的.


附:     
碰巧前些天看IBM的Open source,注意到eclipse写着遵循OSGI规范,写build文件时想了起来,顺手google了一下,还真找到了. STEP2的功能8其实就是把STEP1整合进去了.最终利用ant直接调动eclipse的JavaCodeFormatter接口,就可以执行代码格式化操作了.
ex:  eclipse -vm <path to virtual machine> -application org.eclipse.jdt.core.JavaCodeFormatter -config <configFile> <files>
更多的eclipse外调方法,可查看
http://grepcode.com/file/repository.grepcode.com/java/eclipse.org/3.6/org.eclipse.jdt/core/3.6.0/org/eclipse/jdt/core/formatter/CodeFormatterApplication.java?av=f
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值