1、SVG 可缩放矢量图
SVG不会像位图一样随着缩放而降低图片质量,优点在于节省空间与内存,多用于小图标。
svg是由 xml 文件定义的,根节点是 svg,但是在Android通过 Vector 对 svg 的支持,根节点是 vector ,获得一张 svg 需要先进行转换才能在android中使用。
res——>new——>Vector Asset
点开一看 哇 仿佛发现了新大陆,在这里我们可以拿到非常多,并且有意思的小玩意,同是我们可以导入本地的SVG、PSD格式的图片,
但是在这里要提醒,PSD 不支持 渐变 和 透明度
我们在xml文件中如何去使用这个矢量图呢?
好,我们再回来,前面我们看到Android识别的是vector节点的,而我们本地的svg图片是 svg 节点的,所以我们不能够拿来直接用,难道我们要一个一个导入么?当然不是,我们有神器:
批量转换SVG
我们使用这个jar包,可以实现批量生成我们Android中能够识别的节点的图片,使用时需要用cmd命令执行
具体的命令执行:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190328095054156.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmd5b25naGFvMTMy,size_16,color_FFFFFF,t_70)java -jar svg2vector-cli-1.0.0.jar -d . -o convert -h 20 -w 20
-jar jar文件路径
-d 指定SVG文件所在目录
-f 指定单个SVG文件
-h 设置转换后SVG的高
-w 设置转换后SVG的宽
-o 输出Android Vector图像目录
// 将SVG图片生成制定维度的png图片 (界限为5.0)
vectorDrawables.generatedDensities('xhdpi','xxhdpi')
// 使用support-v7兼容
vectorDrawables.useSupportLibrary=true
SVG很神奇的解决了套图(单套)的问题,500张不同分辨率的图精简100张,nice
2、Tint着色器
刚才我们说,解决一套图的优化,嘛呢多套图又该如何呢。下面我们就来说说tint属性
Tint能够实现图片变色,利用tint显示不同颜色的图片,原本需要多张相同图片不同颜色的情况,能够减少apk的体积。
我们首先来实现静态的变色:
可以看出来我们直接设置tint属性即可,那么当然我们点击事件也是可以响应的了,请看小生继续分解:
不管你点击与不点击,图片都是一张,解决套图的根本,我们获取焦点之后改变颜色的配置请看下面
drawable文件配置
color文件配置
点击事件能够响应,同时运用在其他控件上同样适用:
选中事件的效果
3、资源配置
资源的映射文件,里面包含如下图所示的多种语言,我们在开发过程中可以干掉我们不需要的闲置资源,只保留我们需要的资源。
那么这些语言怎么来的呢?——这些语言是由于v7包的引入。
那么假如说:我们在string.xml文件中有上百条,上千条数据 string ,那么每种语言就会有一整套这样的语言
针对上面这种情况,这个时候他的作用就非常大了:
//只保留指定和默认的资源
resConfigs ('zh-rCN','ko')
4、动态打包配置
如果项目中包含了第三方SDK或者自己使用了NDK,如果不进行配置会打包全CPU架构的动态库进apk,对于真机,只需要保留一个armeabi(armeabi-v7)就可以了。
//配置so库架构 (真机:arm,模拟器:x86)
ndk{
abiFilters('armeabi', 'armeabi-v7a')
}
sourceSets{
main{
jniLibs.srcDirs=['libs']
}
}
这种方式可以极大降低APK的体积!
5、移除无用资源(物理删除)
一键移除如果出现使用动态id使用资源会出现问题
这是没有用到的无用资源
我们说第一种方式:
两种删除方式都是物理性的删除,是不可恢复的,都会直接干掉,效果如下图:
虽说他的缺点有些不够人性化,但是效果还是很好的,可以有效清理我们开发过程中闲置的资源
所以提示 在使用之前,最好是先备份res资源文件;
6、代码混淆、压缩
//开启源代码混淆
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
其中,proguard-rules.pro文件内容为混淆代码:
-ignorewarnings
-dontskipnonpubliclibraryclassmembers
-keepattributes SourceFile,LineNumberTable
-keep class * implements java.io.Serializable {
*;
}
-keep class **.R$* {*;}
#supportv4
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
# fastjson
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
...
...
...
附上一篇混淆很详细的语法介绍:https://www.jianshu.com/p/7e0a6faeb882
7、启用资源缩减
//启动资源压缩
shrinkResources true
我们这种资源的压缩与第五种最大的不同,使我们保留了代码文件,只是不打包进入apk,这是灵魂的删除,值得使用。
8、启用webp转换插件
WebP (发音"weppy"),是一种同时提供了有损压缩与无损压缩的图片文件格式,这种图片格式相比png或者jpg格式的图片损失的质量几乎可以忽略不计,但是压缩后的体积却比png和jpg要小很多。
亲测一个1.7M的png图片经过webp转换之后可以压缩到小于100k,而且质量没有明显的损失。(大小是可调的)
目前谷歌已经将这种压缩格式集成到studio中
那么具体该怎么操作呢,嘿嘿
哎呀,又get到了 ,好开心呀是不是,别着急,咱们还有哦
9、压缩对齐,res资源混淆(apk包)
资源混淆配合7zip压缩,减小apk大小,增加破解难度
通过resource.arsc文件格式,混淆步骤为
1. 解析arsc文件,主要为全局与资源名字符串池
2. 修改字符串池中的字符串,以无意义的a/b替换
3. 修改apk中的res目录资源文件名
4. 打包(7zip)、对齐、签名
可以使用微信团队开源的AndResGuard进行资源混淆
具体用法:
项目根目录下build.gradle中,添加插件的依赖
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.15'
在app目录下,创建and_res_guard.gradle文件(也可以直接将内容写入build.gradle文件)
apply plugin: 'AndResGuard'
andResGuard {
// mappingFile = file("./resource_mapping.txt")
mappingFile = null
use7zip = true
useSign = true
// 打开这个开关,会keep住所有资源的原始路径,只混淆资源的名字
keepRoot = false
whiteList = [
// for your icon
"R.drawable.icon",
// for fabric
"R.string.com.crashlytics.*",
// for google-services
"R.string.google_app_id",
"R.string.gcm_defaultSenderId",
"R.string.default_web_client_id",
"R.string.ga_trackingId",
"R.string.firebase_database_url",
"R.string.google_api_key",
"R.string.google_crash_reporting_api_key",
// 我在实际项目中遇到第三方使用getIdentifier访问的资源的问题,将指定的资源放入白名单后,虽然不闪退了,但还是会出现无法理解的错误。所以只好全部id都放入白名单
"R.id.*"
]
compressFilePattern = [
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
]
sevenzip {
artifact = 'com.tencent.mm:SevenZip:1.2.15'
//path = "/usr/local/bin/7za"
}
/**
* 可选: 如果不设置则会默认覆盖assemble输出的apk
**/
// finalApkBackupPath = "${project.rootDir}/final.apk"
/**
* 可选: 指定v1签名时生成jar文件的摘要算法
* 默认值为“SHA-1”
**/
// digestalg = "SHA-256"
}
在build.gradle文件中引用
apply from: 'and_res_guard.gradle'
集成完AndResGuard后,在app的gradle的tasks中,多了一个叫做andresguard的task
如果打debug包,执行resguardDebug指令;
如果打preview包,执行resguardPreview指令;
如果打release包,执行resguardRelease指令。
我们双击执行resguardRelease指令,执行完毕后,我们可以在app目录下的/build/output/apk/release/AndResGuard_{apk_name}/ 文件夹中找到混淆后的Apk