小M自从前次发布了新版 IDEA 插件之后,Assistant 新颖的接入方法收到了共同好评,可是第一版的 Assistant 只有介绍和基础接入功用,老板期望小M多加一些功用,比方像 Fireb: d B 6 A _ lase 接入的时L ~ { A Q k候,有按z ; m * Y 钮显示接入状况,能够 aX = 6 ]ppI W + 5 ? b Hly 一些 GradF * G Z # E Ele 的插件等等功用。

Ⅰ 起源 —— Acti: ? q t }on

这些必定难不倒小 M,咱们只要参考下 firebase 的集成就好了。其实~ K h x F | 1 e咱们大部分业务开发都是根据“事情”这个模e r n 0 r I R型的,包含普通的 Web 后端和前端上的开发,$ ] 8 n 1 ] n [IDEA 相关的内容也不例外,IDEA 呼应的用户的动作一般都是 Action,比方点击菜单里的某一项,便是呼应 AnAction 的操作。比方咱们举个例子,在之前 Assistant 相关的 xml 中,有如下代码:

<action key="mpaas.integrate_dependencies" laa # E ; & M Zbel="点击增加">
...K i j , r R G t.
</action>

咱们需求对这个 Ak b b q t A Fction 做处理,根据之前 firebase 相关的集成方法,首要需求在 plugin.xml 中注册如下内容:

<extensions defaultExtensionNs="com.android.tools.idea.assistant">
<actionHandler implementation="com.alipay.mpaas.assistant.actions.MPIntegrate! [ } -BaselineActionH? + 2 x U O { Wa1 5 p ^ndler" />x # ) u A # v ;
</extens- @ R _ = Iions>

在这个类中,复写`getId()`办法

class MPIntegrateBaselineActionHandler: AssistAca ~ Q G ytionHandler {
companion object {
const val ACTION_KEY = "mpaas.integrate_depT 8 4 }endencies"
}
override fun getId() = ACTION_KEY
}

这样就和上面 xml 中的内容对应上了,它供给了一个 handlAction 办法,咱们能够在这儿写逻辑

  override fun hc ! p WandleAction(actionData: AcP i Q f | fti[ M ? { M l VonData, project: Project) {
....
}

那这儿便是小助手和咱们代码连接的地方了,经过以上的阐明,关于呼应事) Z D L D k H情这件事,咱们就现已做完R m m /S 5 0

Ⅱ 操作 Gradle 文件

第二步,便是操作 Gradles $ 6 + 文件了。 IDEA` x ) 插件里边V K 6 u i其实没有内置 GrP b 8 .adl@ U ] de 引擎(明显也不合算),可是它通过 Psi 供给了对 Gradle DSL 解析的弱支撑(不是完整支撑)。同时供给了一些语W 1 +义化的模型来简化这个问题。

咱们注意到 Android Studio 供给了这么一个类 GradleBuildModel 在 Anroid Studio 3.6 中,它供给的接口如下:

看 android / buildscript / dependencies /x a D [ 4 7 ext 咱们立刻能够知道,这儿对应咱们 build.gradle 中几个 DSL 的 block,比方咱们需求往 buildscripT F 2 st 中加入特定的 maven,用来拉取 sdk 或者 gradle 插件的话,那么按如下方法操作:

① 获取与修正 GradleBuildModel

GradleModelProv[ N ~ zider.get().getBm ) m F KuildModel(project)
//or
GradleModelProvider.get().getBuildModel(mW Z & w c ] H ]odule) 

GradleBuildModel 一般是在 sync 完成之后,会被 AS 缓存起来,咱们能以 O(1@ T 7) 的功率去获取,然后咱们这边还是以 buildscriptU * y 3 7 为例,它对o D n * Y B { i应 BuildScriptModel,在 build.gradle 中的内容如下d c ` !

buildscript {
ext.mpaas_artifact = "mpaas-baseG S lline"
ext.mpaaT I 0 6 g }s_baseline = n F 6 V B 8 w F"10.1.68-5"
repositories {
mavenCentra` g ; _ X K ^ .l()
jcenter()
google()
}
dependencies {
classpath 'com.i f ?android.tools.build:gradle:3.6.3'
}
}

那么咱们往`repositoB 2 * f = I O – Eries`增加一个阿里云的 maven 库房的方法就很简单了,咱们调用`RepositoriesModel`的`addMavet O 7 c !nRepositoryByUrl`办法

repositor. ; C liesModel.addMavenRepositor= s H ^ ] [ `yByUrl(] - 8  ! H . N w"https://maven.aliyun.com/repository/central")

p A q H . + % K 回写 GradleBu l N ^ )ildModel

这一步改完后,在 BuildModelp b / L l ~ . T 就**暂存**了刚刚的内容,咱G k z | N们还需求把这块内容回写回去:

WriteCommandAction.runWriteCommandAction(project, buildModel::applyChanges)

终究完成作用如下:

③ 增加杂乱 Maven DSL 表达式

当然,上面视频里边展现的作用i n J g v是增加一个比较杂乱的 maven 装备,有 name / credential 等装备,由于 R} # i S C ^epositoriesModel 只给咱们供给了增加 url 一种方法,假如想完成以上的作用,咱们需求使用反射的方法,操作 GradleDslBlockModel 的方法来进行。

val myDslElementField = GradleDslBlockModela F /::cl$ Y 7 u y t f tass.java.gT k 4etDeclaredFielh ! `d("myDslElement")
myDslElementField.isAccessible = true
val myDslElement: GradlePropertiesDslElement = myDslElementField.get(repositoryModel) as Grad% ^ D V rlePropertiesDslElement
val nameElement = GI e *radleNameElement.create(W B A Y & # 9 G ?"maven")
val mavenDslElement = MavenRepositoryDslElement(myDslEo t H e alement, nameElZ Q , 1ement)
val mavenCredentialsDslElement = MavenCredentialsDslElement(mavenDslElement)
mavenCredentialsDslElement.setNewLiteral(K 4 d +"username", "xxx")
mave. e ; v =nCre/ : & h 0 3 W s Zdenti: u 3 = 1 j I ! 8alsDslElement.setNewLiteral("passwordv Q E h 6 Z  1 `"t ] h | Z ), "xxx")
mavenDslElement.setNewLiteral("url", ALIPAY_MAVEN_URL)
mavenDsl* @ $Element.setNewLiteral("nameN g A x = J k Z [", "alipay")
mavenDslElement.addParsedElement(mavenCredentialsDslElement)
myDslElement.setNewElu n L ? / + hement(mavenDslElement)

Ⅲ AF o J . GcI 4 @ = c 1tion 状况办理

点完这个按钮后,假如能有一个提示来告诉用n 8 b + q D户是否接入成功,这简直就太好啦:

image.png

这需求j . # y一个叫 ActionSt= 7 h 4 8 j q kateManager 的组件

<extensions defaultExtensionNs="com.android.tG 4 : u G n d v ools.idea.assistant">
<actionStateManager implementation="com.alipk @ c T _ay6 . . r `.mpaas.assistant.actio{ L U m i ; 5 I )ns.MPIntegrateBaselineStateManager" />& t x ) 8 #;
</extensions>

& + O S !们同时也来写一个* ? j I 9 5 T这样的组件,它承继于 AssistActionStateManager 里边有几个类需求复写

image.png

这儿的 getId() 返回你刚刚注册 Action 的那个 id 即可,我这儿q X j / D f S |便是 mpaas.integrate_dependencies 这儿咱们 getState() 支撑返回的状况有这么几种能够选:

image.png

当然,你也能够根据提示自己新建一种状况,按照这个枚举的名字,和里边参数的界说,咱们能知道每一种状况代表的意义。F 7 , ; D = 2

由于这个类的生/ . t N q x & i r命周期没有相关的回调,假如咱们需求这个类的实例,因而咱们需求在 AS 调用 inu X ^ Q Z ] Cit 办法的时候,自己拿到它的实例存起来。

—— END ——