Android Studio Plugin 外掛開發教程(二) —— 外掛SDK中的常用物件介紹

boredream發表於2017-08-28

專案原始碼

github.com/boredream/A…

系列教程

Android Studio Plugin 外掛開發教程(一) —— 開發你的第一個外掛

Android Studio Plugin 外掛開發教程(二) —— 外掛SDK中的常用物件介紹

Android Studio Plugin 外掛開發教程(三) —— 製作一個自動生成資料庫程式碼的外掛

Android Studio Plugin 外掛開發教程(四) —— 為自動生成資料庫程式碼的外掛新增UI


先樹立一個概念,AS裡專案的一切都可以視為物件,比如整個專案,專案裡的每個檔案,檔案裡的每個方法、每行語句等等都是一個物件。我們外掛SDK的開發,主要工作就是針對這一個個的物件的分析和處理

下面開始介紹幾個主要的物件類

Virtual File

虛擬檔案類。
可以當做Java開發中的File物件理解,概念比較類似

獲取方法

  • 通過Action獲取: event.getData(PlatformDataKeys.VIRTUAL_FILE).
    這個也是之前教程(一)中的獲取方法
  • 通過本地檔案路徑獲取: LocalFileSystem.getInstance().findFileByIoFile()
  • 通過PSI file獲取: psiFile.getVirtualFile()
  • 通過document獲取: FileDocumentManager.getInstance().getFile()

用處

傳統的檔案操作方法這個物件都支援,比如獲取檔案內容,重新命名,移動,刪除等


PSI File

PSI系統下的檔案類。

獲取方法

  • 通過Action獲取: e.getData(LangDataKeys.PSI_FILE).
  • 通過VirtualFile獲取: PsiManager.getInstance(project).findFile()
  • 通過document獲取: PsiDocumentManager.getInstance(project).getPsiFile()
  • 通過檔案中的Element元素獲取: psiElement.getContainingFile()
    如果要通過名字獲取,請使用 FilenameIndex.getFilesByName(project, name, scope)

用處

作為PSI系統中的一個元素,可以使用PSI Element的各種具體方法


看到這裡肯定很多人一臉迷惑,這倆File有啥區別?PSI是啥?Element又是啥?

什麼是PSI系統?

PSI 是 Program Structure Interface 的簡寫。從名字可以看出來它是一個介面,相當於把專案中的一切都封裝了起來,比如類、方法、語句等,讓他們都成為了同一個系統內的實現。封裝的物件類都統一加了個字首比如PsiClass、PsiMethod等。

Virtual File 和 PSI File的區別?

如果學過Dom和Parse解析就很好理解了,Virtual File就是xml檔案本身的一個抽象物件。而PSI File就類似於Dom下xml檔案解析成的Document物件,雖然也是“檔案”,但是特殊封裝過的~ 這個PsiFile是整個PSI系統下的檔案物件,和PSI下的其他Element元素相通~

PSI Element是什麼?

PSI Element是PSI系統下不同型別物件的一個統稱,是基類。
比如之前提到的PsiMethod、PsiClass等等都是一個個具體的PsiElement實現。


可能還會有點迷惑,下面寫個demo幫助理解。
我們通過ActionEvent的getData方法,傳入對應KEY獲取PsiFile(Action類建立參考上篇教程),然後遍歷PsiFile檔案下所有的子級元素,列印出來(日誌顯示在開發外掛的IDE的控制檯)
注意,這個直接獲取的PsiFile預設為當前我們當前所選的檔案

@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 呼叫我們編寫的外掛
執行結果日誌如下:

PsiPackageStatement:com.boredream.plugindemo
PsiWhiteSpace
PsiImportList
PsiWhiteSpace
PsiClass:MainActivity
PsiWhiteSpace

這裡把MainActivity檔案下所有的子級Element都列出來了(只遍歷直接子級)
看名字就能知道意思,PsiPackageStatement是包名語句,PsiClass是類。。。甚至還有PsiWhiteSpace,空白都專門有個型別啊!細緻!

這裡不同的Element還有自己對應的特殊方法,比如PsiClass就和Java中的Class類似,可以獲取Field、Method等。下面我們再簡單改造下Demo,獲取MainActivity檔案中Class裡面的元素。

@Override
public void actionPerformed(AnActionEvent e) {
    PsiFile file = e.getData(PlatformDataKeys.PSI_FILE);
    for (PsiElement psiElement : file.getChildren()) {
        if(psiElement instanceof PsiClass) {
            PsiClass clazz = (PsiClass) psiElement;
            PsiMethod method = clazz.getMethods()[0];
            System.out.println(method.getName());
            System.out.println(method.getParameterList().getText());
        }
    }
}複製程式碼

同樣,再次run專案,然後呼叫外掛
執行結果日誌如下:

onCreate
(Bundle savedInstanceState)

這次我們遍歷獲取了PsiClass類物件,然後獲取它內部的第一個方法,並列印方法的名字和方法引數的文字

本篇教程結束~
下一章,我們將開擼 自動生成資料庫外掛程式碼的實戰~
然後一邊寫外掛一邊再學習新的內容

相關文章