关于Android Gradle你需要知道这些(4)

前言

上一篇文章,我们实现了一个简单的Gradle 插件,并打印出了Hello world。打通了对于插件开发的流程,导师之前写了一个检测目录资源的Gradle插件,看了其源码后,自己准备完全用groovy来实现一个帮助我么定位出工程中的大文件,比如一个大的资源文件,一个类文件,我们可以迅速定位到相关文件,做分析,是否需要对资源文件压缩,或者类文件是否需要重构。当然大的类不一定都是需要我们去重构的类。

本着简洁代码的原则,带着我们的需求来做相应的开发。

实现思路

实现的思路比较简单。在Build文件执行完成之后,也就是在Project的afterEvaluate方法中,来遍历当前的文件目录,然后计算当前文件的大小,根据设置的数据来保存下相应的文件信息。最后打印出来。

插件的实现

  • 定义插件类

向Task中传递我们当前Java目录和资源目录,然后还有定义的对于资源数量的限制的数目。

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类来
实现。

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来实现的

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来表示每一个文件,主要包含文件的路径信息和大小。

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并不管用)

这个时候也意识到在网上写文章一定要对与自己的读者负责,如果你不能够去把一个技术细节讲好,那么也不要把其讲错,否则就是在给后来人挖一个大坑。

网上针对上传到Jcenter的文章有很多,针对其中具体的步骤也就不再展开了。对于上传主要步骤。对于其中的配置项在配置时要仔细。这里丢一个链接 Gradle之使用Android Studio 编写Gradle插件并上传Library到JCenter

  • 注册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插件相关知识梳理到了第四篇了,最近事情比较多,对于这系列文章的开始定为更多的是一个入门系列,针对一些知识点进行梳理。认识这个东西,并能够利用它做一些东西,对于具体的深入还需要我们花时间去看相应文档去做更深层次的研究,当然对于基本开发的应用,其已经基本满足需求了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,106评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,654评论 18 139
  • 随意哈拉阅读 281评论 0 0
  • 我曾以为独自一人身处异乡是为孤,陌生到没有一块砖有被你踩过的痕迹,没有一盏灯是为了等你去亮起,因为灯需要有开启它的...
    抽刀断水丶阅读 208评论 0 0
  • 经典同学很有意思,平时从他文章里就能看出是一个很有观点的人。我看着他头像一直以为是个女的,没想到竟然是90后的男孩...
    广陵十四阅读 387评论 4 3