前言
虽是AndroidStudio插件开发,但由于AndroidStudio是基于IDEA的,所以AndroidStudio插件开发,其实也是IDEA插件开发。
插件开发环境配置
去IDEA官网下载IDEA。
IDEA分为社区版(Community Edition)和旗舰版(Ultimate Edition)
- 社区版:完全免费,代码开源,但是缺少一些旗舰版中的高级特性。
- 旗舰版:30天免费,支持全部功能,代码不开源。
AndroidStudio插件开发下载Community 版本即可.下载后傻瓜式安装,一直下一步.
创建Plugin工程
目前来说,IDEA插件工程有两种模式,第一种是直接在IDEA中创建插件开发的项目,第二种是使用Gradle来构建Intellij插件。下面两种方式都会介绍下:
方式一:IDEA中新建plugin项目
-
创建plugin项目:
- 在创建项目时选择IntelliJ Platform Plugin
- Project SDK需要选择插件开发特有的SDK(注意不是JDK),没有相应的SDK需要new一个
- 可以根据自己需要开发的插件选择相应的库和框架(可选,后期可再增加)
这时就完成了插件项目的创建,如下所示:
可以看到创建出的project非常的简单,仅在META-INF文件夹中有一个plugin.xml配置文件~plugin.xml配置文件会在后面具体介绍。
方式二:使用Gradle来构建Intellij插件
作为一个Android开发人员,gradle的好处大家都懂。
创建好的Gradle项目中会出现一堆与Gradle相关的文件夹和文件,这个时候只需要关注build.gradle即可。
- 添加 IntelliJ build plugins仓库地址
plugins {
id 'org.jetbrains.intellij' version '0.3.1'
}
- 使用IntelliJ IDEA的插件
apply plugin: "org.jetbrains.intellij"
apply plugin: 'java'
apply plugin: 'idea
- 设置运行插件的IntelliJ的版本以及沙箱地址
intellij {
version = '***.**' //调试我们插件的版本
sandboxDirectory = project.rootDir.canonicalPath + "/.sandbox" //插件生成的临时文件的地址,可以省略
}
两种创建方式的差异
项目本身的差异
- SDK的差异:
- 使用IDEA创建的插件项目中SDK为 IDEA插件专用的SDK
- 使用Gradle编译的插件项目SDK为 JDK
- idea.iml文件中type不同
- 使用IDEA创建的插件项目中xxx.iml中type为PLUGIN_MODULE
- 使用Gradle编译的插件项目中xxx.iml中type为JAVA_MODULE
运行方式的差异
-
旧版本IDEA,对于创建的插件项目在运行时需要创建一个plugin的运行方式
- Use classpath of module:选择当前的module即可,这里需要注意如果xxx.iml文件中type不为PLUGIN_MODULE那么这里将会找不到该MODULE,会报Run Configuration Error: No plugin module specified for configuration错误
- JRE选择插件SDK默认JRE
最新版IDEA中创建插件项目时已经自动增加运行方式,无需再创建
同样对于使用Gradle编译的插件项目,旧版本IDEA,需要创建gradle的运行方式。并将Tasks设置为 :runIde
plugin.xml
IDEA插件的工程创建完毕后,都会在META目录下创建一个plugin.xml文件,类似Android的AndroidMainFest.xml,就是一些配置项
创建后文件中大概方式为
<idea-plugin>
<id>com.your.company.unique.plugin.id</id>
<name>Plugin display name here</name>
<version>1.0</version>
<vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>
<description><![CDATA[
Enter short description for your plugin here.<br>
<em>most HTML tags may be used</em>
]]></description>
<change-notes><![CDATA[
Add change notes here.<br>
<em>most HTML tags may be used</em>
]]>
</change-notes>
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
<idea-version since-build="173.0"/>
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
on how to target different products -->
<!-- uncomment to enable plugin in all products
<depends>com.intellij.modules.lang</depends>
-->
<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
</extensions>
<actions>
<!-- Add your actions here -->
</actions>
</idea-plugin>
-
大概解释下其中各个标签作用
- id:表示当前插件的唯一id号
- name:插件的名称
- version:插件的版本号
- vendor:填写开发人的邮箱,公司名称
- description:插件的描述,如果将插件上传到IDEA的仓库后,在进行下载的时候就会显示该描述
- idea-version:表示当前插件所支持的所有Intellij Idea 的版本, 详细信息可以参照这个对应关系
- extensions:这里一般会放一些我们自己的扩展的东西,比如新增高亮显示,新增语言支持都是需要在这里进行扩展
- actions:新增的Action类需要在这里注册,用于菜单栏扩展
一些在此配置的id、name、versio、description等信息,即是在插件下载选择页时看到的信息
=============到此完成项目创建================
AnAction
当我们想扩展IDEA提供的菜单栏,那么就可以通过创建Action类来实现相应的功能。
创建Action
创建Action有两种方式:
- 方式1:创建一个类,然后继承AnAction类,通过重写其actionPerformed()方法,,最后需要在Plugin.xml中进行配置
-
方式2: 通过IDEA提供的界面进行创建,并重写其actionPerformed()方法,如下图所示
actionPerformed() 方法即为点击对应action菜单项回调执行的方法
在用方式2生成时,会弹出如下截图属性 | 描述 |
---|---|
Action ID | 这个Action的唯一标示 |
Class Name | 类名,即自定义继承AnAction的子类名 |
Name | 这个action在菜单上的名称 |
Description | 这个action描述信息 |
Groups | group-id决定着当前group或者action显示在工具栏的具体地方,如果如图所示,CodeMenu代表在Code菜单下 |
Anchor | anchor决定着该action或者group显示在该工具栏的具体地方,first代表第一位 |
KeyboardShortcuts | 代表唤起action的快捷方式,同AndroidStudiowwS中我们设置各种快捷方式一样,图中设置 ⌘+⇧+A |
点击OK后对应pligin.xml多出如下action元素,这些元素与我们创建时所填写信息相对应,我们如果通过方式1创建action即需要写这些配置,同理,我们通过方式2创建的action,后期也可以根据自身需要再手动更改。
创建界面
这时我们就需要用到Java Swing的相关api了,我们知道连整个IDEA界面都是用Java Swing实现的。
所以参加复杂的功能肯定离不开Java Swing,这又是另外一片大海。官方文档在此 不做详述。
在此我们仅实现简单的弹窗功能。在actionPerformed利用如下sdk封好的方法
@Override
public void actionPerformed(AnActionEvent anActionEvent) {
// TODO: insert com.peyton.base64.action logic here
Messages.showDialog("testContent","testTitle",new String[]{"OK"},-1,null);
}
运行及调试
开发时点击运行按钮,即可打开另一个IDEA窗口(如果没有则自己手动创建一个项目),在该窗口中即是模拟插件安装所在IDE,在该窗口中可调试、查看插件效果
发布及安装
- 生成jar或zip包 点击Bulid菜单下的Prepare Plugin按钮会在项目的根目录生成插件的jar或zip包。如果插件无其它引用则为jar包,有其它等依赖则为zip包。将该jar或zip包,发给需要的人员,然后在setting-->Plugin-->Install plugin from disk 选择对应jar或zip包即可
- 还可以把插件发布到仓库,让其他人也能使用,进入JetBrains官网,注册账号,提交插件jar包,填写相关信息,等待审核就可以了。
最终运行效果
小拓展
自定义菜单组
以上只是简单将action放在ide一级菜单中,当然我们还可以定义自己的菜单组,然后加入一级菜单中.我们在plugin.xml中配置如下代码,自定义二级菜单列表
...
<actions>
<!-- Add your actions here -->
<group id="MyTestGroup" text="TestGroup" description="Just Test Group extension" popup="true">
<!-- 中间有action删减 -->
<add-to-group group-id="RefactoringMenu" anchor="last"/>
<action id="MyFirstAction" class="com.peyton.testproject.action.FristActinClass" text="ShowInMyGroup"
description="展示基本dialog">
<add-to-group group-id="RefactoringMenu" anchor="first"/>
<keyboard-shortcut keymap="$default" first-keystroke="shift ctrl A"/>
</action>
</group>
</actions>
...
效果则如图
重写update函数
为了响应用户的点击事件,我们重写了actionPerformed方法。在actionPerformed方法中执行一些响应的逻辑,比如弹出一个对话框,在打开的class中自动生成相关的代码等操作。
但是有时候我们定义的插件只在某些场景中才可以使用,比如说我们编写自动生成代码的插件时,只有当文件打开且是相应的类型时才能正常执行;如果不符合条件,就应该将插件按钮置为不能点击。
当我们不希望用户点击我们定义的插件时,我们可以将插件隐藏,让用户无法看到插件,只有当符合插件执行的环境时,才让插件在菜单中显示~
这时为了能让用户在点击自定义插件对应的菜单栏之前动态判断该插件是否能够点击,只需要重写update函数。
update什么时候被回调呢?在IDEA中有很多的菜单栏,比如help,Window,Tools等等,当点击这些菜单栏使得Action菜单项显示出来时,就会回调update函数。
update或actionPerformed函数被回调时,会传入AnActionEvent对象,通过AnActionEvent对象我们可以判断出当前编辑框是否打开等实时的IDEA环境状况。