前言
在我们日常的开发中经常会使用到各种各样的AS插件,比如Android ButterKnife Zelezny,能方便我们快速生成ButterKnife相关代码,JSON To Kotlin Class,可以通过一段json数据去生成data class,等等。这些插件极大地提高了我们的开发效率。然而之前一直都只是停留在使用阶段,最近基于公司项目的架构开发了一款快速生成模板代码的插件,在此记录并总结一下AS插件开发的一点经验。
准备工作
官方推荐我们使用IDEA去开发插件,一般我们使用社区版的idea就好了,附上下载链接。然后一路安装就ok了。另外,社区版的idea源码也是公开的(jetbrains永远的神),有兴趣你甚至可以自己编译属于你自己版本的idea,附上IDEA源码。
官方文档
网上关于AS插件开发的教程不算太多,必要时候还得多翻翻官方开发文档。不过u1s1,纯英文的文档看起来也确实费劲,我个人推荐多去看看开源插件的源码。废话少说,下面进入正题。
创建plugin工程的方式
1. 在IDEA中新建plugin项目:
- 创建项目时选择IntelliJ Platform Plugin
- Project SDK需要选择插件开发特有的SDK(非JDK)
2.使用Gradle来构建插件项目
不同于第一种方式,这里使用的Project SDK就是指JDK。下面的依赖中Intellij Platform plugin这一项最好勾选,它会帮助我们添加相关的依赖和生成plugin.xml文件。其他选项可以根据自己的需求添加,我这里用到了Kotlin。然后点击next,项目就创建完成。
此时还需要在工程的build.gradle文件中添加相关依赖才能支持构建Intellij Plugin:
1.使用intellij插件
plugins {
id 'java'
id 'org.jetbrains.intellij' version '0.4.22'
id 'org.jetbrains.kotlin.jvm' version '1.4.0'
}
如果上一步勾选了Intellij Platform plugin,这一步忽略
2.设置运行插件的IntelliJ的版本
intellij {
version '2019.3'
}
可以理解为我们开发APP时设置的TargetSdkVersion
3.添加对Android平台库的依赖
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
compileOnly fileTree(dir: "$StudioCompilePath/plugins/android/lib", include: ['*.jar'])
compileOnly fileTree(dir: "$StudioCompilePath/plugins/java/lib", include: ['*.jar'])
compileOnly fileTree(dir: "$StudioCompilePath/lib", include: ['*.jar'])
testCompile fileTree(dir: "$StudioCompilePath/plugins/android/lib", include: ['*.jar'])
testCompile fileTree(dir: "$StudioCompilePath/plugins/java/lib", include: ['*.jar'])
testCompile fileTree(dir: "$StudioCompilePath/lib", include: ['*.jar'])
testCompile group: 'junit', name: 'junit', version: '4.12'
}
因为我们的插件在运行时是基于AS,所以这些依赖只需要参加编译即可
4.指定你本地的AS安装路径
也就是上一步指定的$StudioCompilePath
这个变量,我们需要在工程的gradle.properties文件中去指定。我Mac环境的配置如下:
5.在resources/META_INF/plugin.xml文件中添加相关依赖(重要)
这个plugin.xml的作用类似APP开发中的manifest.xml文件。我在之前开发过程中由于缺少对org.jetbrains.android的依赖,导致在解析Android项目时一直报相关的类找不到~_~||
附一份完整的build.gradle配置:
两种创建方式对比
- SDK的差异
- 使用IDEA创建的插件项目中SDK为IDEA插件专用的SDK
- 使用Gradle编译的插件项目SDK为JDK
- IDEA.iml文件中type不同
- 使用IDEA创建的插件项目中xxx.iml中type为PLUGIN_MODULE
- 使用Gradle编译的插件项目中xxx.iml中type为JAVA_MODULE
官方文档上的总结是IDEA创建的插件适用于功能比较简单的插件,对于功能比较复杂的插件建议使用Gradle
关于plugin.xml
IDEA插件的工程创建完毕后,都会在META目录下创建一个plugin.xml文件,可以将它理解为AndroidMainFest.xml,里面定义了一些组件、事件等需要注册的内容。
几个属性:
- id:表示当前插件的唯一id号
- name:插件的名称
- version:插件的版本号
- vendor:填写开发人的邮箱,公司名称
- description:插件的描述,如果将插件上传到IDEA的仓库后,在进行下载的时候就会显示该描述
- idea-version:表示当前插件所支持的所有Intellij Idea 的版本, 详细信息可以参照这个对应关系
- extensions:这里一般会放一些我们自己的扩展的东西,比如新增高亮显示,新增语言支持都是需要在这里进行扩展
- actions:新增的Action类需要在这里注册,用于菜单栏扩展
创建第一个Action
AnAction
至此一个intellij plugin的项目就已经创建好了,接下来正式开始激动人心的插件开发。首先需要先介绍一个非常重要的类:AnAction。根据官方文档的说法, AnAction表示具有状态、表示和可执行的实体。这样说太抽象,结合使用场景来说,当我们想扩展IDEA提供的菜单栏,那么就可以通过创建Action类来实现相应的功能。
创建AnAction
创建一个Action有两种方式:
1.新建一个类去继承AnAction
,需要重写其actionPerformed()方法和update()方法,最后需要在Plugin.xml中进行配置
2.通过IDEA提供的界面进行创建,并重写其actionPerformed()方法和update()方法:
区别就是使用第二种方式创建时需要填写相关的配置信息,如id、name、快捷键等等:
具体的Action配置的关键信息:
- group id:多个Action的组合,id需要唯一
- group text:工具栏中group显示的信息
- group icon:group图标
- group popup:action是否为弹出
- action id:action ID,需要唯一
- action class:具体的Action实现类的全限定名
- action text:当前action在工具栏中的展示信息
- add-to-group:group-id决定着当前group或者action显示在工具栏的具体地方,anchor决定着该action或者group显示在该工具栏的具体地方。
这里就随便填填,然后点击ok,这样一个Action就创建好了,查看plugin.xml文件,找到我们刚刚创建好的HelloAction
:
然后去实现HelloAction
的actionPerformed
方法,当我们点击这个Action时actionPerformed
方法就会被执行。这里我们简单的去实现一下这个方法,点击后会弹出一个弹窗:
然后点击运行:
就会启动一个新的IntelliJIDEA的界面,在这个IDEA顶部的view菜单中,可以找到我们定义的HelloPlugin
:
点击HelloPlugin
:
这样一个最简单的Intellij plugin就实现了,在下一篇文章中会实现一些更复杂的功能,包括如何解析一个Android项目,如何生成类文件,资源文件等等。