【Intellij Idea 插件 番外】使用Gradle編譯插件,解決中文亂碼

簡介

本篇博客主要是介紹Intellij Idea 插件開發過程中,使用Gradle進行編譯時(默認是Ant),配置和使用相關的問題。由於官方文檔此處說的不是特別明白,我在此將自己的配置進行講解,並講解如何解決使用Gradle 編譯時出現中文亂碼問題。如有錯誤,請在留言中指正,謝謝。 系列彙總地址


實踐

爲什麼要使用Gradle

肯定有很多人還是有疑惑,既然Gradle使用起來還需要看各種配置,而且還有各種坑,爲什麼還要使用Gradle 呢? 其原因就需要知道GradleAnt的區別了,其實和EclipseAndroid Studio 的比較一樣,使用Ant的時候你的依賴需要下各種jar包,進行手動依賴,Gradle 只需配置好對應的Mavent 倉庫,然後設置好依賴的庫的名字和版本即可,方便程度不言而喻。想想eclipse 再想想Android Studio 是不是已經迫不及待開始搞起了?好,下面我開始講如何使用Gradle 編譯插件。

配置Gradle

首先我們選擇File->New Project,然後按照下圖步驟操作:

設置項目

圖1

步驟如下:第一步選擇Gradle,第二步選擇Project SDK(此處如果不明白可去基礎的AnAction,瞭解Project SDK 相關知識),第三步 選擇Next

然後,顯示如圖所示:

設置項目

圖2

此處,會讓你配置GroupId以及ArtifactIdVersion這些信息。你可以根據自己的需求進行配置即可,沒特別要求,然後一路默認選擇Next ,最後選擇Finish,這樣就完成了,官方教程也大概只寫到這裏。

此時你看到的目錄結構應該如下所示:

設置項目

圖3

此時,依照圖3 ,依次展開src->main->java ,你可以在此處新建包,然後新建你的java類,使用java 去編寫插件。當然,如果你需要使用kotlin的話,首先需要在src->main 下新建一個kotlin 文件夾,和java 同級,將你的kotlin代碼放置此處即可,不過僅僅如此還不夠,還需要修改build.gradle的配置,後續講解build.gradle的配置的時候會具體說明。

爲了你的Gradle 編譯的插件能夠使用,還需要新建一個plugin.xml 文件,放置在src->main->resources->META-INF(沒有的自行新建) 目錄下,注意要選擇UTF-8編碼,否則不支持中文哦。plugin.xml 的內容可以參考下方代碼:

<idea-plugin>
    <!--這個需要唯一id,用於標識你的plugin(必填,且唯一)-->
    <id>com.simon.plugin.gradle.demo</id>
    <!--這個用於顯示你的plugin name(必填)-->
    <name>GradleDemoPluginName</name>
    <!--這個地方填寫你的plugin version,gradle 配置的以build.gradle內的爲準-->
    <version>1.0</version>
    <!--郵箱和公司地址和公司名稱-->
    <vendor email="[email protected]" url="http://www.yourcompany.com">YourCompany</vendor>
    <!--插件的內容描述-->
    <description><![CDATA[
    ]]></description>
    <!--插件的更新日誌-->
    <change-notes><![CDATA[
    ]]>
    </change-notes>

    <!--編譯支持的版本,類似android的版本限制-->
    <idea-version since-build="145.0"/>


    <extensions defaultExtensionNs="com.intellij">
        <!-- Add your extensions here -->
    </extensions>

    <actions>
        <!-- Add your actions here -->
    </actions>

</idea-plugin>

當然僅僅如此還不夠,還需要配置你的build.gradle 文件,配置如下:

// 1.配置倉庫
buildscript {
    //kotlin 版本配置,不需要kotlin的可刪除此處
    ext.kotlin_version = '1.2.0'
    //倉庫地址配置
    repositories {
        mavenCentral()
        maven {
            url "https://oss.sonatype.org/content/repositories/snapshots/"
        }
        maven {
            url 'http://dl.bintray.com/jetbrains/intellij-plugin-service'
        }

    }
    dependencies {
        classpath "org.jetbrains.intellij.plugins:gradle-intellij-plugin:0.3.0-SNAPSHOT"
        //kotlin 配置,不需要kotlin的可刪除此處
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

//2.插件 配置
plugins {
    id "org.jetbrains.intellij" version '0.2.17'
}

//2.1 插件配置
// 這兩個插件是必備
apply plugin: 'idea'
apply plugin: 'org.jetbrains.intellij'
//編譯java必備
apply plugin: 'java'
//編譯kotlin必備(不需要Kotlin的可刪除此處)
apply plugin: 'kotlin'

//2.2
//此處也必須設置用於 下載kotlin和其他庫
repositories {
    mavenCentral()
}

//3.此處是用於設置基於的intellij的版本 並且會下載源碼!!
intellij {
    //此處版本需要按照後面的配置一致,否則此處報錯!!!!(IC-version)
    version '173.3727.127' //這個是你要下載的源碼的版本,參考此處https://www.jetbrains.com/intellij-repository/releases
    plugins 'coverage' //Bundled plugin dependencies
    pluginName 'gradle_config_plugin'//插件的名稱
}
//4.依賴
dependencies {
    //此處用於填寫你所依賴的內容,比如此處依賴kotlin(不需要Kotlin的可刪除此處)
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}

//配置生成的Intellij Idea 的插件相關內容
group 'GradleConfigDemo'
//此處配置版本後,plugin.xml中的配置將失效
version '1.0-SNAPSHOT'

上面的註釋應該足夠清晰了,註釋中表示只有當使用kotlin時才需要的配置,視是否使用kotlin決定是否配置即可,其他的按照上面的配置即可。

當然如果你覺得麻煩,或者仍然配置有問題,可以下載此文件複製過來即可。

那麼,怎麼知道是否配置成功呢 ?

你可以按照如下步驟進行查看:

設置項目

圖4

如果最後顯示瞭如圖所示的Task ,則說明配置成功了。

如何同時兼容JavaKotlin的編譯呢?

在此之前我們應該在build.gradle 裏面配置了kotlin有關的依賴,然後在src下面建立main文件夾,再分別建javakotlin文件夾,內部分別存放對應的代碼即可。不理解的地方,可以參照此文件,進行配置。

如何使用Gradle 進行編譯呢?

  • Gradle 直接運行:你可以看剛纔的圖4,裏面顯示了Tasksintellij內 ,它有個runIdeTask,你可以使用命令gradle runIde 或者直接點擊 上圖中顯示的位置即可,使用命令的前提需要配置好Gradle的環境,具體如何配置Gradle環境自行百度。
  • Gradle 編譯後導入運行:你可以直接使用gradle clean(清理編譯內容),然後使用gradle build 即可完成項目編譯。

    注意:這些Gradle命令,運行的前提首要的是需要配置對應的環境,其次必須在項目的文件路徑上執行(切換到項目的文件目錄),或者使用IDE 下面的terminal,它已經切換路徑到當前項目的文件目錄了,可以直接輸入Gradle 命令。

Gradle 編譯的內容在哪呢?如何使用?

我們剛纔看圖2中項目的文件目錄結構,當你編譯過後,它裏面會有個build文件夾,是用於存儲生成的文件的,然後點擊打開可以看到idea-sanbox,然後再打開可以看到plugins,再打開看到的就是與你的plugin name 相同名稱的文件夾,將此文件夾打包成zip格式即可導入到intellij idea 平臺ide 使用。

注意:gradle clean 會清除build 文件夾以及文件夾內的內容。

到此,你已經完成了所有的Gradle的配置,現在應該是可以編譯和運行了,如果還有配置不清楚的,請參考此文件

解決Gradle中文亂碼

當你開開心心的使用Gradle編譯完成後,然後安裝上你的插件,你這時候會發現你的插件說明中,中文成了亂碼,如果你使用的都是英文的話,那就當我沒說….

當時遇見這個問題的時候感覺很奇怪,爲什麼會出現亂碼呢?明明Ant編譯的時候並沒有問題啊,爲什麼Gradle 編譯就有問題了呢?那既然改變的條件是這個,那就應該從此處出發。

然後我解壓了打包後的插件,發現裏面的plugin.xml的編碼方式爲Ansi ,而我原本的plugin.xml文件是UTF-8的,而Ant打包後是UTF-8。繼續下扒,由於Ansi 格式的文件,是無法正常顯示中文的,這個地方應該是關鍵問題。既然如此,我們去扒一下Gradle打包期間的流程,我們打包的時候,使用了gradle-intellij-plugin 插件,我們去看下它的源碼,後面終於找到了有關xml打包TaskPatchPluginXmlTask),下面看下它的關鍵代碼:

@TaskAction
    void patchPluginXmlFiles() {
        def files = getPluginXmlFiles()
        files.each { file ->
            def pluginXml = Utils.parseXml(file)

            patchTag(pluginXml, "idea-version", null, [
                    "since-build": getSinceBuild(),
                    "until-build": getUntilBuild()])
            patchTag(pluginXml, "description", getPluginDescription())
            patchTag(pluginXml, "change-notes", getChangeNotes())
            patchTagIf(getVersion() != Project.DEFAULT_VERSION,
                    pluginXml, "version", getVersion())
            patchTag(pluginXml, "id", getPluginId())

            def writer
            try {
                //核心原因就是因爲此處,使用了FileWriter,它的文件格式默認就是Ansi的
                writer = new PrintWriter(new FileWriter(new File(getDestinationDir(), file.getName())))
                def printer = new XmlNodePrinter(writer)
                printer.preserveWhitespace = true
                printer.print(pluginXml)
            }
            finally {
                if (writer) {
                    writer.close()
                }
            }
        }
    }

通過上面的註釋我們看到了原因,就是使用了FileWriter,所以導致無法成爲UTF-8格式的文件,好,既然如此,我們怎麼去修改呢? 看了下它的參數,似乎沒有給予修改文件編碼的方式,那我們只能自己修改了,那怎麼修改呢?後面思考後,可以在PatchPluginXmlTask 後面加個功能,完成xml文件的格式轉換,具體代碼如下:

//-----------------------------------change xml file encoding---------------------------------------------
project.patchPluginXml.doLast {
    loopFileDirectoryChangeFileEncoding((File) project.patchPluginXml.getDestinationDir())
}
/**
 *  Traverse the folder, modifying the file format to utf-8
 */
void loopFileDirectoryChangeFileEncoding(File xmlFileDirectory) {
    //check directory
    if (xmlFileDirectory != null && xmlFileDirectory.isDirectory()) {
        File[] files = xmlFileDirectory.listFiles()
        //loop file
        for (File tempXmlFile : files) {
            if (tempXmlFile.isFile()) {
                String xmlPath = tempXmlFile.getPath()
                project.changeFileEncodingToUtf8(xmlPath)
            }
        }
    }
}
/**
 * Modifying the xml file to utf - 8
 */
void changeFileEncodingToUtf8(String xmlPath) {
    try {
        //read xml file
        BufferedReader bfr = new BufferedReader(new FileReader(xmlPath))
        String line = bfr.readLine()
        StringBuilder sb = new StringBuilder()
        while (line != null) {
            sb.append(line)
            sb.append("\n")
            line = bfr.readLine()
        }
        bfr.close()
        //write xml file
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(xmlPath, false), "UTF-8"))
        writer.write(sb.toString())
        writer.flush()
        writer.close()
    } catch (IOException e) {
        System.out.println("read err:" + e.toString())
    }
}

上面的代碼可以放到你的build.gradle的最下面,即可,然後可以正常的編譯,運行,無需額外操作,即可。上面的原理就是將編譯完成的xml文件修改爲UTF-8編碼,好,問題解決~


總結

至此已經基本瞭解了Intellij Idea 的插件中,使用Gradle進行編譯時,配置和使用過程中可能遇到的問題和解決方案,溫故知新,內容持續加入中,敬請期待~

學完了內容後,多回顧多思考,繼續後續內容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章