Android技术知识Android开发经验谈Android开发

AndroidStudio 代码生成插件Code Generat

2018-05-30  本文已影响42人  zii4914

前言

前几天在做MVP迁移,把项目旧代码替换为使用MVP,给我的感觉就是重重复复的体力劳动。MVP项目平常的开发,要多建几个类,多十几个接口方法。像一些TextView的setText,及View的Visibility、Enable操作,写的特烦,然后发现一个特好用的代码生成插件,批量生成对应的方法。

安装

原Github地址
我的GitHub(入口放在倒数第一项,方便操作)

  1. 到Release页,下载Jar文件。
  2. AS中Plugins选择从磁盘安装。

使用

1.Alt + Insert 调出Generate窗口
2.选择CodeGenerate
3.选择需要生成的模板
4.选择针对的变量
5.点击ok生成


配置和自定义模板



类选择框
成员变量选择框
 Tutorial for writing your templates

 1. First you need to know basic syntax of velocity[1].
 2. Then it is necessary to understand the variable that CodeGenerator provides
    and its inner structure for retrieving the information you need for generating code.
 3. Learn to use the utils provided so that you can ask for further information
    or reduce your workload.

 Variables Provided (Class Mode)
 -------------------------------
 Class mode means you want to create new classes(file).

 - ClassName: String     The name spcified by `Target Class Name`
 - PackageName: String   The package name specified by `Target Class Name`
 - class0: ClassEntry    The class that the action is triggered upon
   - raw: PsiClass
   - String packageName
   - importList: List<String>
   - fields: List<FieldEntry>
   - allFields: List<FieldEntry>
   - methods: List<MethodEntry>
   - allMethods: List<MethodEntry>
   - innerClasses: List<ClassEntry>
   - allInnerClasses: List<ClassEntry>
   - typeParamList:  List<String>
   - name: String
   - superName: String
   - superQualifiedName: String
   - qualifiedName: String
   - typeParams: int
   - hasSuper: boolean
   - deprecated: boolean
   - enum: boolean
   - exception: boolean
   - abstract: boolean
   - implementNames: String[]
   - isImplements(String): bool
   - isExtends(String): bool
   - matchName(String): bool

 - class1: ClassEntry    The first selected class, where `1` is the postfix
                         you specify in pipeline
   ...

 - MemberEntry (FieldEntry/MethodEntry common properties)
    - raw: PsiField(for field), PsiMethod(for method)
    - name: String
    - accessor: String
    - array: boolean
    - nestedArray: boolean
    - collection: boolean
    - map: boolean
    - primitive: boolean
    - string: boolean
    - primitiveArray: boolean
    - objectArray: boolean
    - numeric: boolean
    - object: boolean
    - date: boolean
    - set: boolean
    - list: boolean
    - stringArray: boolean
    - calendar: boolean
    - typeName: String
    - typeQualifiedName: String     //包含路径
    - type: String
    - boolean: boolean
    - long: boolean
    - float: boolean
    - double: boolean
    - void: boolean
    - notNull: boolean
    - char: boolean
    - byte: boolean
    - short: boolean
    - modifierStatic: boolean
    - modifierPublic: boolean
    - modifierProtected: boolean
    - modifierPackageLocal: boolean
    - modifierPrivate: boolean
    - modifierFinal: boolean

 - FieldEntry
   - constant: boolean
   - modifierTransient: boolean
   - modifierVolatile: boolean
   - enum: boolean
   - matchName(String): bool

 - MethodEntry
   - methodName: String
   - fieldName: String
   - modifierAbstract: boolean
   - modifierSynchronzied: boolean
   - modifierSynchronized: boolean
   - returnTypeVoid: boolean
   - getter: boolean
   - deprecated: boolean
   - matchName(String): bool

 Variables for Body Mode
 -----------------------
 - class0: ClassEntry         The current class
 - fields: List<FieldEntry>   All selected fields
 - methods: List<MethodEntry> All selected methods
 - members: List<MemberEntry> selected fields+methods
 - parentMethod: MethodEntry  The nearest method that surround the current cursor

 Utilities
 ---------
 - settings: CodeStyleSettings settings of code style
 - project: Project            The project instance, normally used by Psi related utilities
 - helper: GenerationHelper
 - StringUtil: Class
 - NameUtil: Class
 - PsiShortNamesCache: Class   utility to search classes
 - PsiJavaPsiFacade: Class     Java specific utility to search classes
 - GlobalSearchScope: Class    class to create search scopes, used by above utilities
 - EntryFactory: Class         EntryFactory.of(...) to turn PsiXXX to XXXEntry.

 Other feature
 -------------
 - Auto import.      If the generated code contains full qualified name, Code Generator will try to
                     import the packages automatically and shorten the name.
                     For example `java.util.List<>` -> `List<>`

 References
 ----------
 - Velocity syntax: http://velocity.apache.org/engine/1.7/user-guide.html

另外一个比较需要的方法,就是查找集成指定的类的 成员变量,比如我要给找出所有继承了View的成员变量,然后统一生成setVisibilityXXX()方法方法。因为在MVP时候,经常用到这个,还有TextView的setTextXXX(),都是只有View和TextView才拥有的方法。下面这个是在Member选项卡中的代码,作用是过滤所有继承android.view.View这个类的成员变量。

 Specified Class Type Filter
 -------------
 #set($typeTarget = "android.view.View")

 #set($availableMembers = $class0.members)
 #set($javaPsiFacade = $JavaPsiFacade.getInstance($project))
 #set($global = $GlobalSearchScope.allScope($project))
 #set($xtype = $javaPsiFacade.findClass($typeTarget, $global))

 #set($availableMembers = [])
 #set($methodNames = [])

 #foreach($member in $class0.members)
     #set($memberType = $member.type.split("&lt;").get(0))
     #set($type = $javaPsiFacade.findClass($memberType, $global))
     #if ($type.qualifiedName == $typeTarget || $type.isInheritor($xtype, true))
         $availableMembers.add($member)
     #end
 #end

我的模板

之前对项目进行MVP重构时候,很烦那些setText()、setEnabled()、setVisibility()之类的,所以找到了这个控件,然后简单下学了一下自定义,自己写了模板,需要的可以直接把文件拿下来导入使用。根目录下code-generator-my-setting.xml文件。
另外,因为原插件入口位置并不是在倒数第一项,强迫症的自己为了方便使用,把源码拿下来重新配置了一下,入口固定在倒数第一项,很方便,感兴趣,可以下项目中的jar(重新编译之后的插件)导入使用。
GitHub

总结

在生成代码方面,该插件的功能绝对是最强大的,最灵活,完全自定义,还可以选择指定类。只要配置了一次模板,就可以一劳永逸。
唯一的缺憾就是不支持文件生成,否则MVP模式的文件也无需手动创建了。

上一篇下一篇

猜你喜欢

热点阅读