Android Studio Plugin开发小记(三)

/ 0评 / 0

前言

系列文档:点这里

常用对象介绍

在上一篇中我们介绍了如何响应Action,主要操作都是在actionPerformed方法中,要想实现真正需要的功能,我们需要熟悉以下几个对象

Project

获取如下,通过Project对象我们能获取到使用此插件的项目的一些基础信息

private void project(AnActionEvent e) {
    Project project = e.getData(PlatformDataKeys.PROJECT);
    //这里的项目指的是运行插件的项目
    //获取项目名字    projectName
    System.out.println(project.getName());
    //获取项目的根目录  C:/Users/hc/IdeaProjects/projectName
    System.out.println(project.getBasePath());
    //获取项目工程文件  C:/Users/hc/IdeaProjects/projectName/.idea/misc.xml
    System.out.println(project.getProjectFilePath());
    //获取workspace文件 C:/Users/hc/IdeaProjects/projectName/.idea/workspace.xml
    System.out.println(project.getWorkspaceFile());
}

VirtualFile

虚拟文件类。可以当做Java开发中的File对象理解,概念比较类似

获取方法

private void virtualFile(AnActionEvent e) {
    //获取当前选中的文件
    VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);

    //通过File对象来获取
    //Project project = e.getData(PlatformDataKeys.PROJECT);
    //VirtualFile ioFile = LocalFileSystem.getInstance().findFileByIoFile(new File(project.getBasePath() + File.separator + "src"));
    //System.out.println(ioFile.getPath());

    //通过路径来获取
    //VirtualFile file = LocalFileSystem.getInstance().findFileByPath(project.getBasePath() + File.separator + "src");

    //通过PsiFile对象来获取
    //psiFile.getVirtualFile()

    //文件/文件夹的绝对路径
    System.out.println(virtualFile.getCanonicalPath());
    //同上 当前选中文件/文件夹的绝对路径
    System.out.println(virtualFile.getPath());

    //获取文件类型
    System.out.println(virtualFile.getFileType());


    //根据扩展名获取文件类型
    //PlainTextFileType 文本文件
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("md"));
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("txt"));
    //ArchiveFileType
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("jar"));
    //UnknownFileType
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("aar"));
    //GroovyFileType
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("gradle"));
    //XmlFileType
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("xml"));
    //KotlinFileType
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("kt"));
    //JavaFileType
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("java"));
    //C++
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("c"));
    //JsonFileType
    System.out.println(FileTypeRegistry.getInstance().getFileTypeByExtension("json"));

    //刷新文件
    virtualFile.refresh(false, false);
    //获取文件扩展名
    //virtualFile.getExtension();

    //virtualFile.getInputStream();
    //virtualFile.getOutputStream()

    //在当前目录下面搜索  不存在返回null
    //virtualFile.findChild("");

    //PS:其实使用File类去操作也可以
}

用处传统的文件操作方法这个对象都支持,比如获取文件内容,重命名,移动,删除,还可以刷新文件目录等

PS:特别需要注意Project project = e.getData(PlatformDataKeys.PROJECT);这种获取方式,当我们目前选中某个文件/文件夹的时候,获取到的就是这个文件/文件夹。其实我们在插件项目中也可以直接使用File对象去操作

PsiFile

PSI系统下的文件类,表示的一个文档,类似于js中的Document对象,可以用来遍历文件中的"对象",比如class、method、field等。

private void psiFile(AnActionEvent e) {
    //获取当前选中的文件,如果不是File 则为null
    PsiFile file = e.getData(PlatformDataKeys.PSI_FILE);

    //通过VirtualFile获取
    //Project project = e.getData(PlatformDataKeys.PROJECT);
    //VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(project.getBasePath() + File.separator + "src");
    //PsiManager.getInstance(project).findFile(virtualFile);

    //获取文件类型  目录会直接NullPointerException
    if (file.getFileType() instanceof JavaFileType) {
        PsiElement[] children = file.getChildren();

        for (PsiElement i : children) {

            if (i instanceof PsiClass) {
                PsiClass ls = (PsiClass) i;
                PsiMethod[] methods = ls.getMethods();

                for (PsiMethod ii : methods) {
                    System.out.println(ii.getName());
                }
            }
        }
    }
}

显示UI

原生UI

有时候我们的插件是需要与用户交互的,所以我们需要显示弹窗与用户交互,这个使用Java-GUI即可,由于我对这个也不熟,而且与插件内容无关,所以就不多介绍。

AS UI

当我们完成操作以后需要提醒用户,我们可以直接弹窗,比如下面的代码就会弹出一个提示框

Messages.showInfoMessage("this is msg", "title");

当然我们也可以弹出通知,就是右下角的,如下代码是从其他插件中抽取的

public class NotificationHelper {

    private static final NotificationGroup INFO = NotificationGroup.logOnlyGroup("ADB Idea (Logging)");
    private static final NotificationGroup ERRORS = NotificationGroup.balloonGroup("ADB Idea (Errors)");
    private static final NotificationListener NOOP_LISTENER = (notification, event) -> {
    };

    public static void info(String message) {
        sendNotification(message, NotificationType.INFORMATION, INFO);
    }

    public static void error(String message) {
        sendNotification(message, NotificationType.ERROR, ERRORS);
    }

    private static void sendNotification(String message, NotificationType notificationType, NotificationGroup notificationGroup) {
        notificationGroup.createNotification("ADB IDEA", escapeString(message), notificationType, NOOP_LISTENER).notify(null);
    }


    private static String escapeString(String string) {
        return string.replaceAll("\n", "\n<br />");
    }
}

进阶

通过一系列的介绍,你已经可以编写一些简单的插件了,不过如果需要进阶,你就需要Read The Fucking Source Code,所以推荐几个插件源码

ADB Idea: https://github.com/CB2Git/adb-idea

JsonToKotlinClass:https://github.com/wuseal/JsonToKotlinClass

TinyPngPlugin:https://github.com/Deemonser/TinyPngPlugin

发表评论

您的电子邮箱地址不会被公开。