前言
雖是AndroidStudio插件開(kāi)發(fā),但由于AndroidStudio是基于IDEA的,所以AndroidStudio插件開(kāi)發(fā),其實(shí)也是IDEA插件開(kāi)發(fā)购桑。
插件開(kāi)發(fā)環(huán)境配置
去IDEA官網(wǎng)下載IDEA。
IDEA分為社區(qū)版(Community Edition)和旗艦版(Ultimate Edition)
- 社區(qū)版:完全免費(fèi)氏淑,代碼開(kāi)源勃蜘,但是缺少一些旗艦版中的高級(jí)特性。
- 旗艦版:30天免費(fèi)假残,支持全部功能缭贡,代碼不開(kāi)源。
AndroidStudio插件開(kāi)發(fā)下載Community 版本即可.下載后傻瓜式安裝辉懒,一直下一步.
創(chuàng)建Plugin工程
目前來(lái)說(shuō)阳惹,IDEA插件工程有兩種模式,第一種是直接在IDEA中創(chuàng)建插件開(kāi)發(fā)的項(xiàng)目眶俩,第二種是使用Gradle來(lái)構(gòu)建Intellij插件莹汤。下面兩種方式都會(huì)介紹下:
方式一:IDEA中新建plugin項(xiàng)目
-
創(chuàng)建plugin項(xiàng)目:
- 在創(chuàng)建項(xiàng)目時(shí)選擇IntelliJ Platform Plugin
- Project SDK需要選擇插件開(kāi)發(fā)特有的SDK(注意不是JDK),沒(méi)有相應(yīng)的SDK需要new一個(gè)
- 可以根據(jù)自己需要開(kāi)發(fā)的插件選擇相應(yīng)的庫(kù)和框架(可選颠印,后期可再增加)
這時(shí)就完成了插件項(xiàng)目的創(chuàng)建纲岭,如下所示:
可以看到創(chuàng)建出的project非常的簡(jiǎn)單抹竹,僅在META-INF文件夾中有一個(gè)plugin.xml配置文件~plugin.xml配置文件會(huì)在后面具體介紹。
方式二:使用Gradle來(lái)構(gòu)建Intellij插件
作為一個(gè)Android開(kāi)發(fā)人員止潮,gradle的好處大家都懂窃判。
創(chuàng)建好的Gradle項(xiàng)目中會(huì)出現(xiàn)一堆與Gradle相關(guān)的文件夾和文件,這個(gè)時(shí)候只需要關(guān)注build.gradle即可喇闸。
- 添加 IntelliJ build plugins倉(cāng)庫(kù)地址
plugins {
id 'org.jetbrains.intellij' version '0.3.1'
}
- 使用IntelliJ IDEA的插件
apply plugin: "org.jetbrains.intellij"
apply plugin: 'java'
apply plugin: 'idea
- 設(shè)置運(yùn)行插件的IntelliJ的版本以及沙箱地址
intellij {
version = '***.**' //調(diào)試我們插件的版本
sandboxDirectory = project.rootDir.canonicalPath + "/.sandbox" //插件生成的臨時(shí)文件的地址袄琳,可以省略
}
兩種創(chuàng)建方式的差異
項(xiàng)目本身的差異
- SDK的差異:
- 使用IDEA創(chuàng)建的插件項(xiàng)目中SDK為 IDEA插件專用的SDK
- 使用Gradle編譯的插件項(xiàng)目SDK為 JDK
- idea.iml文件中type不同
- 使用IDEA創(chuàng)建的插件項(xiàng)目中xxx.iml中type為PLUGIN_MODULE
- 使用Gradle編譯的插件項(xiàng)目中xxx.iml中type為JAVA_MODULE
運(yùn)行方式的差異
-
舊版本IDEA,對(duì)于創(chuàng)建的插件項(xiàng)目在運(yùn)行時(shí)需要?jiǎng)?chuàng)建一個(gè)plugin的運(yùn)行方式
- Use classpath of module:選擇當(dāng)前的module即可燃乍,這里需要注意如果xxx.iml文件中type不為PLUGIN_MODULE那么這里將會(huì)找不到該MODULE唆樊,會(huì)報(bào)Run Configuration Error: No plugin module specified for configuration錯(cuò)誤
- JRE選擇插件SDK默認(rèn)JRE
最新版IDEA中創(chuàng)建插件項(xiàng)目時(shí)已經(jīng)自動(dòng)增加運(yùn)行方式,無(wú)需再創(chuàng)建
同樣對(duì)于使用Gradle編譯的插件項(xiàng)目橘沥,舊版本IDEA窗轩,需要?jiǎng)?chuàng)建gradle的運(yùn)行方式。并將Tasks設(shè)置為 :runIde
plugin.xml
IDEA插件的工程創(chuàng)建完畢后座咆,都會(huì)在META目錄下創(chuàng)建一個(gè)plugin.xml文件,類似Android的AndroidMainFest.xml仓洼,就是一些配置項(xiàng)
創(chuàng)建后文件中大概方式為
<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>
-
大概解釋下其中各個(gè)標(biāo)簽作用
- id:表示當(dāng)前插件的唯一id號(hào)
- name:插件的名稱
- version:插件的版本號(hào)
- vendor:填寫開(kāi)發(fā)人的郵箱介陶,公司名稱
- description:插件的描述,如果將插件上傳到IDEA的倉(cāng)庫(kù)后色建,在進(jìn)行下載的時(shí)候就會(huì)顯示該描述
- idea-version:表示當(dāng)前插件所支持的所有Intellij Idea 的版本, 詳細(xì)信息可以參照這個(gè)對(duì)應(yīng)關(guān)系
- extensions:這里一般會(huì)放一些我們自己的擴(kuò)展的東西哺呜,比如新增高亮顯示,新增語(yǔ)言支持都是需要在這里進(jìn)行擴(kuò)展
- actions:新增的Action類需要在這里注冊(cè)箕戳,用于菜單欄擴(kuò)展
一些在此配置的id某残、name、versio陵吸、description等信息玻墅,即是在插件下載選擇頁(yè)時(shí)看到的信息
=============到此完成項(xiàng)目創(chuàng)建================
AnAction
當(dāng)我們想擴(kuò)展IDEA提供的菜單欄,那么就可以通過(guò)創(chuàng)建Action類來(lái)實(shí)現(xiàn)相應(yīng)的功能壮虫。
創(chuàng)建Action
創(chuàng)建Action有兩種方式:
- 方式1:創(chuàng)建一個(gè)類澳厢,然后繼承AnAction類,通過(guò)重寫其actionPerformed()方法囚似,,最后需要在Plugin.xml中進(jìn)行配置
-
方式2: 通過(guò)IDEA提供的界面進(jìn)行創(chuàng)建剩拢,并重寫其actionPerformed()方法,如下圖所示
actionPerformed() 方法即為點(diǎn)擊對(duì)應(yīng)action菜單項(xiàng)回調(diào)執(zhí)行的方法
在用方式2生成時(shí)饶唤,會(huì)彈出如下截圖屬性 | 描述 |
---|---|
Action ID | 這個(gè)Action的唯一標(biāo)示 |
Class Name | 類名徐伐,即自定義繼承AnAction的子類名 |
Name | 這個(gè)action在菜單上的名稱 |
Description | 這個(gè)action描述信息 |
Groups | group-id決定著當(dāng)前group或者action顯示在工具欄的具體地方,如果如圖所示募狂,CodeMenu代表在Code菜單下 |
Anchor | anchor決定著該action或者group顯示在該工具欄的具體地方办素,first代表第一位 |
KeyboardShortcuts | 代表喚起action的快捷方式角雷,同AndroidStudiowwS中我們?cè)O(shè)置各種快捷方式一樣,圖中設(shè)置 ?+?+A |
點(diǎn)擊OK后對(duì)應(yīng)pligin.xml多出如下action元素摸屠,這些元素與我們創(chuàng)建時(shí)所填寫信息相對(duì)應(yīng)谓罗,我們?nèi)绻ㄟ^(guò)方式1創(chuàng)建action即需要寫這些配置,同理季二,我們通過(guò)方式2創(chuàng)建的action檩咱,后期也可以根據(jù)自身需要再手動(dòng)更改。
創(chuàng)建界面
這時(shí)我們就需要用到Java Swing的相關(guān)api了胯舷,我們知道連整個(gè)IDEA界面都是用Java Swing實(shí)現(xiàn)的刻蚯。
所以參加復(fù)雜的功能肯定離不開(kāi)Java Swing,這又是另外一片大海桑嘶。官方文檔在此 不做詳述炊汹。
在此我們僅實(shí)現(xiàn)簡(jiǎn)單的彈窗功能。在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);
}
運(yùn)行及調(diào)試
開(kāi)發(fā)時(shí)點(diǎn)擊運(yùn)行按鈕逃顶,即可打開(kāi)另一個(gè)IDEA窗口(如果沒(méi)有則自己手動(dòng)創(chuàng)建一個(gè)項(xiàng)目)讨便,在該窗口中即是模擬插件安裝所在IDE,在該窗口中可調(diào)試以政、查看插件效果
發(fā)布及安裝
- 生成jar或zip包 點(diǎn)擊Bulid菜單下的Prepare Plugin按鈕會(huì)在項(xiàng)目的根目錄生成插件的jar或zip包霸褒。如果插件無(wú)其它引用則為jar包,有其它等依賴則為zip包盈蛮。將該jar或zip包废菱,發(fā)給需要的人員,然后在setting-->Plugin-->Install plugin from disk 選擇對(duì)應(yīng)jar或zip包即可
- 還可以把插件發(fā)布到倉(cāng)庫(kù)抖誉,讓其他人也能使用殊轴,進(jìn)入JetBrains官網(wǎng),注冊(cè)賬號(hào)袒炉,提交插件jar包旁理,填寫相關(guān)信息,等待審核就可以了梳杏。
最終運(yùn)行效果
小拓展
自定義菜單組
以上只是簡(jiǎn)單將action放在ide一級(jí)菜單中韧拒,當(dāng)然我們還可以定義自己的菜單組,然后加入一級(jí)菜單中.我們?cè)趐lugin.xml中配置如下代碼,自定義二級(jí)菜單列表
...
<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函數(shù)
為了響應(yīng)用戶的點(diǎn)擊事件十性,我們重寫了actionPerformed方法叛溢。在actionPerformed方法中執(zhí)行一些響應(yīng)的邏輯,比如彈出一個(gè)對(duì)話框劲适,在打開(kāi)的class中自動(dòng)生成相關(guān)的代碼等操作楷掉。
但是有時(shí)候我們定義的插件只在某些場(chǎng)景中才可以使用,比如說(shuō)我們編寫自動(dòng)生成代碼的插件時(shí)霞势,只有當(dāng)文件打開(kāi)且是相應(yīng)的類型時(shí)才能正常執(zhí)行烹植;如果不符合條件斑鸦,就應(yīng)該將插件按鈕置為不能點(diǎn)擊。
當(dāng)我們不希望用戶點(diǎn)擊我們定義的插件時(shí)草雕,我們可以將插件隱藏巷屿,讓用戶無(wú)法看到插件,只有當(dāng)符合插件執(zhí)行的環(huán)境時(shí)墩虹,才讓插件在菜單中顯示~
這時(shí)為了能讓用戶在點(diǎn)擊自定義插件對(duì)應(yīng)的菜單欄之前動(dòng)態(tài)判斷該插件是否能夠點(diǎn)擊嘱巾,只需要重寫update函數(shù)。
update什么時(shí)候被回調(diào)呢诫钓?在IDEA中有很多的菜單欄旬昭,比如help,Window菌湃,Tools等等问拘,當(dāng)點(diǎn)擊這些菜單欄使得Action菜單項(xiàng)顯示出來(lái)時(shí),就會(huì)回調(diào)update函數(shù)惧所。
update或actionPerformed函數(shù)被回調(diào)時(shí)骤坐,會(huì)傳入AnActionEvent對(duì)象,通過(guò)AnActionEvent對(duì)象我們可以判斷出當(dāng)前編輯框是否打開(kāi)等實(shí)時(shí)的IDEA環(huán)境狀況下愈。