
在开发的过程中,我们难免会遇到一些重复性编码的工作,如果能够让这些重复工作变得自动化,那该是一件多么爽的事情,比如我通过打造一个插件,提示了 5%的工作效率。节省下来的时间,干点什么不好呢?
一、首先,什么是插件
说 android studio 插件实际上是指 intellij plugin 上面的插件,只不过,我做好插件之后,是使用在 android stuido 上而已,android stuido 实际上就是 intellij 安装了 android stuido 插件之后的一个独立发布版本包而已。那么 intellij plugin 到底是什么东西,我觉得能用图说话,就尽量避免啰嗦了,这里,我使用我工作中使用的非常频繁的一个插件来说说:

如图上图所示,这是一个可以在 android studio 中使用的翻译插件,它可以说是英语水平不太好的开发的必备法宝之一。
怎么安装的呢?
通常是在这里搜索安装,当然也可以下载开发者发布的 zip(jar)包到本地进行安装。

当然,你也可以通过这里管理你安装的插件,卸载,更新等等。
实际上,除了这个翻译插件,我们在开发的过程中已经不知不觉的用到了很多插件,比如,代码查找,重构,根据 xml 生成 adapter 代码等等,不得不说,没有这些插件,我们的开发效率将会大打折扣。
然而,也些时候,你的需求 intellij plugin 插件仓库中的插件并不能满足你,那么一定是时候自己动手做一个了。
二、动手自己做插件
1、首先上图,这是我自己做的一个插件,实现了一键从 pb 生成网络请求相关的接口文件。

2、我为什么需要在做一个插件
在项目的开发的过程中,我遇到了一个痛点,那就是每次一个新的业务到来,后台就会提供一些请求数据的接口(PB 文件),自然而然,前端为了和后台交互,就需要封装一些请求方法去请求后台了,实际上做着做着,就觉得这部分操作属于枯燥无味的重复性操作:如下:

基本上都是面对一个 pb 文件,写一个 Service,然后,在去写其中的具体的请求方法了。
那么我就在思考怎么突破,:
1、当然想到的第一个可能是后台能不能将这部分代码封装好打包一个 jar 给我们,和后台同学一说,他们觉得我想得可能有点多了,嗯,没时间做,还是你们自己做吧(哈哈,想太多)。
2、有没有什么自动生成代码的方法,了解过一些,比如,https://github.com/square/javapoet但是发现做起可能有点复杂,需要花太多的时间。
3、那么,能不能做一个可以在 android studio 中使用的插件呢?那么为什么不呢?
4、最后,我显然是做好了,如下图所示,基于后台提供的 PB 代码,使用我做好的插件,自动生成了 Service 文件,自动生成了接口请求文件 Presenter,以后后台增加接口,我再也不用写枯燥无味的请求接口了。

三、我获得了哪些好处呢?
实现这个插件之后,我获得了哪些好处呢?
1、开发效率大大提升,我们再也不用为后台 req 封装网络请求了,操作有之前的手写变为了一键无痛生成。
2、servcie 文件,和 presenter 文件都具备统一的命名规范,再也不懂担心开发人员随意命名了,这样一来保持了命名一致性,现在请求后台一个业务接口,我只需要对着 pb 文件就知道该怎么调用那个封装的方法,而不用去具体 presenter 中找了。
3、避免了不同的开发人员做重复的网络请求封装。
4、减低人为封装接口造成的请求参数类型错误而导致浪费调试时间。
整体算起来,解读 pb 文件大约需要 5 分钟,一个请求接口的封装需要 10 分钟,如果调试的时候,发现参数类型,参数个数错误导致接口调试不同,额外花费了 10 多分钟,,后期接口维护,增加参数了,你还得去改封装接口,大概 10 分钟,那么,平均算起来,每次一个请求都大概就去了半小时了。如果使用自动生成组件,这些几乎都是 0 成本了。按一个细分过的需求实现要 9 个小时,那大概每个需求就省去了 5.5%的时间,
四、总结
这里是我做插件的一个过程,也都是从写 Hello World 开始的。
1、创建一个插件工程参考的这里。
https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/creating_plugin_project.html
2、创建一个 action 参考的这里
https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/creating_an_action.html
3、好了,基本上,经过上面的环节,就到了代码编写环节,可能,你已经到了这里了。

4、代码编写环节。
那么,Hello World 肯定是必须玩一玩的,actionPerformed 其实就是当你选择插件中一个功能时,他做什么动作。实际上,这里就是一个调用入口。比如,你可以在这里写上 Hello World.编译,运行,此时会蹦出另外一个 IntelliJ 实例,而且已经安装好了这个插件了,找到这个插件。点击,哈哈,入门了,自此,你已经掌握怎么编写一个简单插件的全部步骤了,就这么简单。那么,这个插件有个卵用?我们要的是能用,那么时候来点提高了。

5、别着急写代码,先做一下需求分析,可行性分析
我这里把我做这个插件的过程拿来分析一下,虽然写的很挫,但是毕竟功能实现了,先来简单的对自己的需求进行一下分析:
a、想要从 pb 文件生成出对应的 service 和 presneter 文件,首先,我们需要知道有哪些 pb 文件,因此,当运行插件的时候,需要弹出一个对话框,告知用户指定 pb 文件目录,程序好取遍历里面的 pb 文件,如果有子目录怎么处理?
b、然后对每个 pb 文件,分析出里面的 Req 请求
![]()
这个就是一个请求了,那么怎么分析,IntelliJ 插件开发框架中是否存在一些库可以分析文件树?那么,拿到这个请求,首先需要在 service 文件中去定义一个接口,需要在 presenter 文件去写一个实现方法,这个该怎么做,是否使用。
c、文件中的 import 怎么处理,不然编译怎么过的了?
d、对于不想生成的 pb 该怎么处理,甚至 pb 里面的某些请求不想处理,咋办,使用配置么,嗯,看来还是对文件的解析操作。
e、对于后期增加文件,是删除重新生成,还是指添加少量代码段,intellij 是否有提供方法,比如往类里添加方法,添加字段等等,是否有类似好用的接口?
6、可行性分析,技术调研,这点很重要,不然可能白忙活半天
那么,我的这些需求到底可行不可行,经过我自己的调研,我大概了解了以下几个概念,就基本断定可行了:
a、VFS 相关(VirtualFileSystem)
https://www.jetbrains.org/intellij/sdk/docs/basics/virtual_file_system.html
提供一个处理文件的通用 API,而不关心文件的具体位置(无论文件位于磁盘上、归档文件中还是 HTTP 服务器上) 追踪文件变化,并且在检测到文件内容发生更改时能提供新旧两个版本的文件 建立文件在 VFS 和持久化存储之间的关联 比如,我做插件的过程中,就用到了 VFS 来定位文件。
![]()
需要注意的是,文件的写操作是需要是需要放到异步线程中去处理的,不然插件会报错,这也是很多平台都具备的特性,耗时操作丢在异步线程,避免主线程卡顿
![]()
b、PSI 相关(Program Structure Interface)
https://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/psi.html
PSI(Program Structure Interface)是 Intellij Platform 中一个非常重要的概念,在 IDE 所管理的 Project 中,每个目录,Package,源代码和资源文件都会被抽象成相应的 PSI 对象。这个好处可以是大大的,比如有这么一些好用的 api
![]()
这就使得我们给已有的内中添加方法提供了便利,而不是去做底层的文件读写操作。还有例如:
![]()
从一段代码创建一个文件,这对于代码生成也是相当有用。这些生成的文件你将其加入到不同的 package 下面,他会自动补上包名 ,等等其他的一些好处。
c、Project Model
https://www.jetbrains.org/intellij/sdk/docs/basics/project_structure.html
提供了一些 api 处理项目结构相关。
7、插件开发这方面的资料非常少,那么,有时候要实现功能,却不知道怎么下手怎么办,有一个可行的办法是,找一个功能有点类似的插件,然后如果 有源码就去 github 上去阅读别人的代码,挖出功能点的实现方式,基本上就能变成自己的了。
8、插件打包,因为我是专用插件,所以我直接打本地包了。打包相当简单,直接
![]()
就会打包出一个 jar 文件,或者 zip 文件,去插件中心安装即可。随后你就可以使用你自己制作的插件啦。
本文转载自公众号云加社区(ID:QcloudCommunity)。
原文链接:
https://mp.weixin.qq.com/s/gN_4VhYGrGQesJCRzuxHxg
评论