先树立一个概念,AS里项目的一切都可以视为对象 比如整个项目,项目里的每个文件,文件里的每个方法、每行语句等等都是一个对象 我们插件SDK的开发,大部分就是针对这一个个的对象进行分析修改
如何获取到这些对象呢? 作为整个插件的入口,Action类中会自动复写一个方法,我们可以通过方法参数ActionEvent获取各种需要的对象 回到上一章的例子中,之前的例子代码如下 可以看到用ActionEvent对象获取到了project项目对象,然后利用它去创建了一个对话框进行交互
1
2
3
4
5
6
7
8
9
10
11
12
13
public class DatabaseGeneratorAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
Project project = e.getData(PlatformDataKeys.PROJECT);
String txt = Messages.showInputDialog(project,
"What is your name?",
"Input your name",
Messages.getQuestionIcon());
Messages.showMessageDialog(project,
"Hello, " + txt + "!\n I am glad to see you.", "Information",
Messages.getInformationIcon());
}
}
同理还可以用这个方法获取其他对象 e.getData(PlatformDataKeys.XXX);
除了Project还有其他各种对象,以及各种获取对象的方法,下面介绍几个主要的
Virtual File
可以当做Java开发中的File对象理解,概念比较类似 获取方法
- From an action: e.getData(PlatformDataKeys.VIRTUAL_FILE).
- From a path in the local file system: LocalFileSystem.getInstance().findFileByIoFile()
- From a PSI file: psiFile.getVirtualFile() (may return null if the PSI file exists only in memory)
- From a document: FileDocumentManager.getInstance().getFile() 用处 传统的文件操作方法这个对象都支持,比如获取文件内容,重命名,移动,删除等
初次之外还有一个File类型
PSI File
PSI系统下的一个文件类 获取方法
- From an action: e.getData(LangDataKeys.PSI_FILE).
- From a VirtualFile: PsiManager.getInstance(project).findFile()
- From a Document: PsiDocumentManager.getInstance(project).getPsiFile()
- From an element inside the file: psiElement.getContainingFile()To find files with a specific name anywhere in the project, use FilenameIndex.getFilesByName(project, name, scope)
用处 作为PSI系统中的一个元素,可以使用PSI Element的各种具体方法
Virtual File 和 PSI File 的区别
如果学过Dom和Parse解析就更好理解了,Virtual File就是xml文件本身的一个抽象对象 而PSI File就是这个xml文件解析成的Document对象,虽然也是“文件”,但是特殊封装过的~ PSI系统和xml解析很像,也有元素的概念,然后有各种具体的元素节点类型,比如PsiMethod啊,PsiClass啊等等
PSI Element
下面具体介绍一下PSI Element,这个也是我们在插件开发中最常打交道的东西 获取方法
- From an action: e.getData(LangDataKeys.PSI_ELEMENT).
- From a file by offset: PsiFile.findElementAt().
- By iterating through a PSI file: using a PsiRecursiveElementWalkingVisitor.
- By resolving a reference: PsiReference.resolve()
基础对象概念简单介绍到这里,下面利用已经学习的内容写个小Demo Action创建略过,参考上一篇 通过ActionEvent的getData方法,传入对应KEY获取PsiFile 然后遍历PsiFile文件下所有的子级元素,打印出来(日志显示在开发插件的IDE的控制台) 注意,这个直接获取的PsiFile默认为当前我们当前所选的文件
1
2
3
4
5
6
@Override
public void actionPerformed(AnActionEvent e) {
PsiFile file = e.getData(PlatformDataKeys.PSI_FILE);
for (PsiElement psiElement : file.getChildren()) {
System.out.println(psiElement);
}
代码run起来 运行起来的IDE我们新建一个Android Project,默认主页面代码如下
然后 Code | Database Generate 调用我们的插件 |
在插件开发的IDE打印台就可以看到输出的日志为
PsiPackageStatement:com.boredream.plugindemo PsiWhiteSpace PsiImportList PsiWhiteSpace PsiClass:MainActivity PsiWhiteSpace
从结果可以看出来,把MainActivity文件下所有的子级Element都列出来了(只遍历直接子级) 看名字就能知道意思,PsiPackageStatement是包名语句,PsiImportList是导包列表,PsiClass是类。。。
不同的Element有自己对应的方法,比如PsiClass就和Java中的Class类似,可以获取Field、Method等, 之后就可以根据自己的需要处理具体逻辑了
下一章,我们就会开始自动生成数据库插件代码的编写实战~
-
Previous
Android Studio Plugin 插件开发教程(一) —— 开发你第一个插件 -
Next
Android Studio Plugin 插件开发教程(三) —— 实现自动生成数据库代码插件