小M自從上次發佈了新版 IDEA 插件以後,Assistant 新穎的接入方式收到了一致好評,可是初版的 Assistant 只有介紹和基礎接入功能,老闆但願小M多加一些功能,好比像 Firebase 接入的時候,有按鈕顯示接入狀態,能夠 apply 一些 Gradle 的插件等等功能。前端
這些確定難不倒小 M,咱們只要參考下 firebase 的集成就行了。其實咱們大部分業務開發都是基於「事件」這個模型的,包括普通的 Web 後端和前端上的開發,IDEA 相關的內容也不例外,IDEA 響應的用戶的動做通常都是 Action,好比點擊菜單裏的某一項,就是響應 AnAction 的操做。好比咱們舉個例子,在以前 Assistant 相關的 xml 中,有以下代碼:
java
<action key="mpaas.integrate_dependencies" label="點擊添加">
....
</action>複製代碼
咱們須要對這個 Action 作處理,根據以前 firebase 相關的集成方式,首先須要在 plugin.xml 中註冊以下內容:
android
<extensions defaultExtensionNs="com.android.tools.idea.assistant">
<actionHandler implementation="com.alipay.mpaas.assistant.actions.MPIntegrateBaselineActionHandler" />
</extensions>複製代碼
在這個類中,複寫`getId()`方法
後端
class MPIntegrateBaselineActionHandler: AssistActionHandler {
companion object {
const val ACTION_KEY = "mpaas.integrate_dependencies"
}
override fun getId() = ACTION_KEY
}複製代碼
這樣就和上面 xml 中的內容對應上了,它提供了一個 handlAction 方法,咱們能夠在這裏寫邏輯
緩存
override fun handleAction(actionData: ActionData, project: Project) {
....
}複製代碼
那這裏就是小助手和咱們代碼鏈接的地方了,通過以上的說明,對於響應事件這件事,咱們就已經作完了。
bash
第二步,就是操做 Gradle 文件了。 IDEA 插件裏面其實沒有內置 Gradle 引擎(顯然也不合算),可是它經過 Psi 提供了對 Gradle DSL 解析的弱支持(不是完整支持)。同時提供了一些語義化的模型來簡化這個問題。app
咱們注意到 Android Studio 提供了這麼一個類 GradleBuildModel
在 Anroid Studio 3.6 中,它提供的接口以下:
maven
看 android / buildscript / dependencies / ext 咱們立刻能夠知道,這裏對應咱們 build.gradle 中幾個 DSL 的 block,好比咱們須要往 buildscript 中加入特定的 maven,用來拉取 sdk 或者 gradle 插件的話,那麼按以下方式操做:
ide
GradleModelProvider.get().getBuildModel(project)
//or
GradleModelProvider.get().getBuildModel(module) 複製代碼
GradleBuildModel 通常是在 sync 完成以後,會被 AS 緩存起來,咱們能以 O(1) 的效率去獲取,而後咱們這邊仍是以 buildscript 爲例,它對應 BuildScriptModel,在 build.gradle 中的內容以下:
post
buildscript {
ext.mpaas_artifact = "mpaas-baseline"
ext.mpaas_baseline = "10.1.68-5"
repositories {
mavenCentral()
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
}
}複製代碼
那麼咱們往`repositories`添加一個阿里雲的 maven 倉庫的方式就很簡單了,咱們調用`RepositoriesModel`的`addMavenRepositoryByUrl`方法
repositoriesModel.addMavenRepositoryByUrl("https://maven.aliyun.com/repository/central")複製代碼
這一步改完後,在 BuildModel 就**暫存**了剛剛的內容,咱們還須要把這塊內容回寫回去:
WriteCommandAction.runWriteCommandAction(project, buildModel::applyChanges)複製代碼
最終實現效果以下:
固然,上面視頻裏面展現的效果是添加一個比較複雜的 maven 配置,有 name / credential 等配置,由於 RepositoriesModel 只給咱們提供了添加 url 一種方式,若是想實現以上的效果,咱們須要使用反射的方式,操做 GradleDslBlockModel 的方式來進行。
val myDslElementField = GradleDslBlockModel::class.java.getDeclaredField("myDslElement")
myDslElementField.isAccessible = true
val myDslElement: GradlePropertiesDslElement = myDslElementField.get(repositoryModel) as GradlePropertiesDslElement
val nameElement = GradleNameElement.create("maven")
val mavenDslElement = MavenRepositoryDslElement(myDslElement, nameElement)
val mavenCredentialsDslElement = MavenCredentialsDslElement(mavenDslElement)
mavenCredentialsDslElement.setNewLiteral("username", "xxx")
mavenCredentialsDslElement.setNewLiteral("password", "xxx")
mavenDslElement.setNewLiteral("url", ALIPAY_MAVEN_URL)
mavenDslElement.setNewLiteral("name", "alipay")
mavenDslElement.addParsedElement(mavenCredentialsDslElement)
myDslElement.setNewElement(mavenDslElement)複製代碼
點完這個按鈕後,若是能有一個提示來告訴用戶是否接入成功,這簡直就太好啦:
這須要一個叫 ActionStateManager 的組件
<extensions defaultExtensionNs="com.android.tools.idea.assistant">
<actionStateManager implementation="com.alipay.mpaas.assistant.actions.MPIntegrateBaselineStateManager" />
</extensions>複製代碼
咱們同時也來寫一個這樣的組件,它繼承於 AssistActionStateManager
裏面有幾個類須要複寫
這裏的 getId()
返回你剛剛註冊 Action 的那個 id 便可,我這裏就是 mpaas.integrate_dependencies
這裏咱們 getState()
支持返回的狀態有這麼幾種能夠選:
固然,你也能夠根據提示本身新建一種狀態,按照這個枚舉的名字,和裏面參數的定義,咱們能知道每一種狀態表明的含義。
由於這個類的生命週期沒有相關的回調,若是咱們須要這個類的實例,所以咱們須要在 AS 調用 init 方法的時候,本身拿到它的實例存起來。
------ END ------