Android图片资源检测插件实现( 二 )


MergeResources
合并资源文件的 task
mergeAssets
MergeAssets
合并 assets 的 task
processResources
ProcessAndroidResources
处理并编译资源文件的 task
generateBuildConfig
GenerateBuildConfig
生成 BuildConfig 类的 task
javaCompile
JavaCompile
编译 Java 源代码的 task
processJavaResources
Copy
处理 Java 资源的 task
assemble
DefaultTask
Variant 的标志性 assemble task
因为我们的插件应该可以应用在主工程或者模块包上的 , 所以当我们插件运行后 , 我们要检测当前使用我们插件的模块是主工程 , 还是模块包
kotlin复制代码val hasAppPlugin = project.plugins.hasPlugin("com.android.application")val variants = if (hasAppPlugin) {(project.property("android") as AppExtension).applicationVariants} else {(project.property("android") as LibraryExtension).libraryVariants}找到想要hock的任务我们想hock住android插件运行的task任务 , 就需要一个重要的gradle回调
erlang复制代码project.afterEvaluate{...}afterEvaluate该方法就是整个gradle配置文件配置成功后的回调 , 证明此时配置已检查完毕 , 所有task已经就绪 , 已经可以开始按指定顺序运行task了 , 那么我就需要在这个回调里办事!

Grade 执行顺序
执行setting , 检测所有module , 为每个模块配置project
加载build.properties , 生成task执行链表和配置
执行某个指定task , 然后会先执行该task所依赖的task
配置完成后 , 开始遍历variants中所有的变体
arduino复制代码project.afterEvaluate {variants.all { variant ->...}}我们的目标task:mergeResourcesProvidermergeResourcesProvider这个任务就是android插件合并所有module中资源的task , 看名字就知道了 。
我们可以从变体中获取这个task对象
ini复制代码val mergeResourcesTask = variant.mergeResourcesProvider.get()那么 , 我们自己的任务呢?
gradle api提供给我们可以在代码中生成task的方法
ini复制代码val mcPicTask = project.task("CheckBigImage${variant.name.capitalize()}")使用project.task("taskname")来生成一个我们自己需要执行的task
然后我们编写这个task的逻辑 , 也是本插件的逻辑
复制代码mcPicTask.doLast {...}variant里面有各种对象 , allRawAndroidResources恰好就是我们需要的 。它只有3.3以上才会有 。
ini复制代码val dir = variant.allRawAndroidResources.files这个dir对象 , 就是android所有文件资源的files集合
ok 。让我们遍历这个文件list吧!
scss复制代码for (channelDir: File in dir) {check(channelDir)}fun check(file: File) { if(file.isDirectory) {check(file)} else {process(file)}}如果遇到文件夹 , 这里是一个递归调用 。
如果遇到文件 , 就可以按照自己的规则处理了 。
挂钩mergeResourcesProvider我们task写好后 , 需要和mergeResourcesProvider挂钩
less复制代码mergeResourcesTask.dependsOn(project.tasks.findByName(mcPicTask.name))使mergeResourcesTask依赖我们的mcPicTask , 当mergeResourcesTask执行前 , 就会先执行我们的mcPicTask了!!
注意:此处直接使用mergeResourcesTask系统task依赖我们的task , 我们的task执行顺序会和mergeResourcesTask原有的依赖混杂在一起 , 不可控 。后面讲一种可控的方法
拦截图片的逻辑这个逻辑应该实现在上面伪代码process(file:File)方法中
  1. 首先我们只需要处理图片 , 所以对参数file进行首轮过滤 , 只留下后缀名为图片的文件
  2. kotlin复制代码
  3. fun isImage(file: File): Boolean { return (file.name.endsWith(Const.JPG) || file.name.endsWith(Const.PNG) || file.name.endsWith(Const.JPEG) || file.name.endsWith(Const.GIF) || file.name.endsWith(Const.WEB_P) ) && !file.name.endsWith(Const.DOT_9PNG)}
  4. 需要检查图片的宽高的话 , 可以使用java的原生api
  5. arduino复制代码
  6. val sourceImg = ImageIO.read(FileInputStream(imgFile))if (sourceImg.height > maxHeight || sourceImg.width > maxWidth) { ...
  7. 需要过滤图片大小的话


    推荐阅读