關於Android Gradle你須要知道這些(4)

前言

上一篇文章,咱們實現了一個簡單的Gradle 插件,並打印出了Hello world。打通了對於插件開發的流程,導師以前寫了一個檢測目錄資源的Gradle插件,看了其源碼後,本身準備徹底用groovy來實現一個幫助我麼定位出工程中的大文件,好比一個大的資源文件,一個類文件,咱們能夠迅速定位到相關文件,作分析,是否須要對資源文件壓縮,或者類文件是否須要重構。固然大的類不必定都是須要咱們去重構的類。java

本着簡潔代碼的原則,帶着咱們的需求來作相應的開發。android

實現思路

實現的思路比較簡單。在Build文件執行完成以後,也就是在Project的afterEvaluate方法中,來遍歷當前的文件目錄,而後計算當前文件的大小,根據設置的數據來保存下相應的文件信息。最後打印出來。api

插件的實現

  • 定義插件類

向Task中傳遞咱們當前Java目錄和資源目錄,而後還有定義的對於資源數量的限制的數目。bash

import org.gradle.api.Plugin
import org.gradle.api.Project

class FileCleaner implements Plugin<Project> {

    @Override
    void apply(Project project) {
        def fileCount = project.extensions.create("fileCount", FileSizeExtension)

        Set<String> paths = new LinkedHashSet<>()
        for (String clazz : project.android.sourceSets.main.java.getSrcDirs()) {
            paths.add(clazz)
        }

        for (String resource : project.android.sourceSets.main.res.getSrcDirs()) {
            paths.add(resource)
        }

        project.afterEvaluate {
            initTask(project, fileCount, paths)
        }
    }

    FileTraverseTask initTask(Project project, FileSizeExtension fileSizeExtension, Set<String> paths) {
        def fileTraverseTask = project.task("filetraverse", type:FileTraverseTask) {
            classCount fileSizeExtension.classCount
            resourceCount fileSizeExtension.resourceCount
            filePaths paths
        }
        return fileTraverseTask
    }
}
複製代碼
  • 定義Task

對於核心功能的實現,主要經過一個這裏定義的一個FileManager類來 實現。app

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

class FileTraverseTask extends DefaultTask {

    int classCount
    int resourceCount
    Set<String> filePaths

    void filePaths(Set<String> values) {
        this.filePaths = values
    }

    @TaskAction
    def traverseFile () {
        FileManager manager = new FileManager(classCount, resourceCount)
        for (String path : filePaths) {
            File file = new File(path)
            manager.traverseFile(file)
        }
        manager.printResult(project.getBuildDir().getAbsolutePath()+File.separator+"/filecleaner.txt")
    }

}
複製代碼
  • 遍歷文件
class FileManager {

    private SortArray classArray
    private SortArray resourceArray

    FileManager (int classCount, int resourceCount) {
        classArray = new SortArray(classCount)
        resourceArray = new SortArray(resourceCount)
    }

    void traverseFile(File file) {
        File[] files = file.listFiles()
        for (File file1 : files) {
            if (file1.directory) {
                traverseFile(file1)
            } else if (file1.file) {
                processFile(file1)
            }
        }
    }

    void processFile(File file) {
        String path = file.absolutePath
        long size = file.size()
        FileItem item = new FileItem()
        item.path = path
        item.size = size

        if (isResource(file.path)) {
            resourceArray.add(item)
        } else {
            classArray.add(item)
        }
    }

    boolean isResource(String path) {
        if (path.contains("main/res")) {
            return true
        } else if (path.contains("main/java")) {
            return false
        }
    }

    void printResult(String fileName) {
        try {
            output(fileName)
        } catch (IOException) {

        }
    }

    void output(String fileName) throws IOException {
        if (classArray.length() == 0 || resourceArray.length() == 0)
            return

        File result = null
        FileWriter writer = null
        result = new File(fileName)
        writer = new FileWriter(result)
        BufferedWriter bufferedWriter = new BufferedWriter(writer)

        bufferedWriter.write("Class size table")
        bufferedWriter.newLine()
        for (int i = 0; i < classArray.length(); i++)  {
            bufferedWriter.write(i+"")
            bufferedWriter.newLine()
            bufferedWriter.write(classArray.getItem(i).toString())
            bufferedWriter.newLine()
        }

        bufferedWriter.newLine()

        bufferedWriter.write("Resource size table")
        bufferedWriter.newLine()

        for (int j = 0;  j < resourceArray.length(); j++) {
            bufferedWriter.write(j+"")
            bufferedWriter.newLine()
            bufferedWriter.write(resourceArray.getItem(j).toString())
            bufferedWriter.newLine()
        }

        bufferedWriter.flush()

        writer.close()
    }

}
複製代碼

對於SortArray內部的是經過LinkedList來實現的maven

class SortArray {

    private LinkedList<FileItem> list
    private int size

     SortArray(int size) {
        this.size = size
        list = new LinkedList<>()
    }

     void add(FileItem item) {
        if (list.size() == 0) {
            list.add(item)
            return
        }

        for (int i = 0; i < list.size(); i++) {
            FileItem tmp = list.get(i)
            if (item.size > tmp.size) {
                list.add(i, item)
                break
            }
        }

         if (list.size() > size) {
             list.removeLast()
         }
    }


    int length() {
        return list.size()
    }

    FileItem getItem(int index) {
        return list.get(index)
    }
    
}
複製代碼

經過FileItem來表示每個文件,主要包含文件的路徑信息和大小。ide

class FileItem {

    private long size
    private String path

     void setSize(long size) {
        this.size = size
    }

    long getSize() {
        return size
    }

    String getPath() {
        return path
    }

    String setPath(String path) {
        this.path = path
    }

    boolean compareTo(FileItem item) {
        if (item == null) {
            return true
        }
        return (this.size - item.size) >= 0 ? true : false
    }

    String toString() {
        return "path:" + path +"\n" + "size:" + size
    }

}
複製代碼

上傳到Jcenter

上傳到Jcenter的過程能夠說是一個很是痛苦的過程,中間遇到了不少的問題,各類配置出問題,並且可能會出現重啓AndroidStudio後,就可上傳成功的相似問題~~~(clean並無論用)gradle

這個時候也意識到在網上寫文章必定要對與本身的讀者負責,若是你不可以去把一個技術細節講好,那麼也不要把其講錯,不然就是在給後來人挖一個大坑。ui

網上針對上傳到Jcenter的文章有不少,針對其中具體的步驟也就再也不展開了。對於上傳主要步驟。對於其中的配置項在配置時要仔細。這裏丟一個連接 Gradle之使用Android Studio 編寫Gradle插件並上傳Library到JCenterthis

  • 註冊Jcenter帳號
  • 添加install配置
  • 添加bintray配置
  • 執行install
  • 執行bintray上傳

Tips:對於Bintray中帳號的註冊,要記得註冊爲我的版,不然會致使上傳項目沒法add link 到jcenter之中。

應用到項目

因爲剛上傳到Jcenter,這裏應用到項目的方式仍是上一篇文章中講的方式,經過本地maven依賴的方式。輸出結果以下。

Class size table
0
path:/Users/chenjensen/AndroidStudioProjects/Graphics/app/src/main/java/com/chenjensen/myapplication/MainActivity.java
size:1019
1
path:/Users/chenjensen/AndroidStudioProjects/Graphics/app/src/main/java/com/chenjensen/myapplication/ExampleService.java
size:735

Resource size table
0
path:/Users/chenjensen/AndroidStudioProjects/Graphics/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
size:14696
1
path:/Users/chenjensen/AndroidStudioProjects/Graphics/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
size:10486
2
path:/Users/chenjensen/AndroidStudioProjects/Graphics/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
size:10056
3
path:/Users/chenjensen/AndroidStudioProjects/Graphics/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
size:7718
4
path:/Users/chenjensen/AndroidStudioProjects/Graphics/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
size:6114

複製代碼

總結

gradle插件相關知識梳理到了第四篇了,最近事情比較多,對於這系列文章的開始定爲更多的是一個入門系列,針對一些知識點進行梳理。認識這個東西,並可以利用它作一些東西,對於具體的深刻還須要咱們花時間去看相應文檔去作更深層次的研究,固然對於基本開發的應用,其已經基本知足需求了。

相關文章
相關標籤/搜索