简书链接:gradle的几个实用技巧让你爽歪歪
文章字数:868,阅读全文大约需要3分钟
本文章由情随事迁收集编写,转载请说明出处

混淆文件收集技巧

自动备份 mapping 混淆发布后对应的真实代码比对文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
applicationVariants.all { variant ->
variant.outputs.each { output ->
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast{
copy {
from variant.mappingFile
into "${projectDir}/mappings"
rename { String fileName ->
"mapping-${variant.name}-${variant.versionName}_${variant.versionCode}.txt"
}
}
}
}
}
}

除此之外还可以切换test目录
将会在项目根目录/mappings/生成文件mapping-release-1.1_2.txt,这样解决了每次发布版本总是需要在build/outputs/release/mapping.txt中找到并移动出来进行备份的问题.
文件自定义字符串混淆的套路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
android.applicationVariants.all {
variant ->
variant.each() {
//buildTypeName:debug,app
println("buildTypeName:" + variant.buildType.name+","+ this.project.name);
}
variant.each {myeach->
//buildTypeName:release,myeach:release
println("buildTypeName:" + variant.buildType.name+",myeach:"+myeach.name+",dir:"+myeach.outputs);
}

variant.outputs.each { output ->
def fileName = "appname_v${variant.versionName}_release_${variant.flavorName}.apk"
if (variant.buildType.isDebuggable()) {
fileName = "appname_v${variant.versionName}_debug_${variant.flavorName}.apk"
}
println("fileName:"+fileName);
// output.outputFile = new File(output.outputFile.parent, fileName)
}
variant.outputs.each {}
}

设置编译时间

1
buildConfigField "long", "BUILD_TIME", System.currentTimeMillis() + "L"

设置这个之后方便查看编译时间,哪怕是开发xposed插件 用这个可以方便查看是否更新生效,根据编译时间来判断.

设置各种目录仿造eclipse目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14

//高仿eclipse结构
sourceSets {
main {
// manifest.srcFile 'AndroidManifest.xml'
// java.srcDirs = ['src']
// resources.srcDirs = ['src']
// aidl.srcDirs = ['src']
// res.srcDirs = ['res']
// assets.srcDirs = ['assets']

jniLibs.srcDirs=['libs']
}
}

合并support版本

作用:解决第三方sdk无法修改但是不得不使用问题

1
2
3
4
5
6
7
8
9
10
11
12
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")
&& !requested.name.startsWith("exifinterface")) {
details.useVersion '24.2.1'
//不设置24.2.1但是设置到了25就找不到布局,全部不管好像又冲突设置24.2.1 那么 要么冲突 要么 java.lang.NoSuchFieldError: No field notification_template_lines of type
}
}
}
}

优化so库压缩体积排除其他平台可自动兼容

1
2
3
4
5
ndk {
//APP的build.gradle设置支持的SO库架构

abiFilters 'armeabi-v7a'
}

这样的话夜神模拟器和真机测试时没毛病的,体积也节省了不少,QQ也是这样做的哈!
缺点就是开发工具会对于没有所指定的会强制不让运行,但是不这样指定的话,如果极光有5个so,但是自己只有一个armebi-v7a的,没法放开,放开也会崩溃,所以还是得下面得方法。

排除指定文件不打包

1
2
3
4
5
6
7
packagingOptions {
exclude "lib/arm64-v8a/libimagepipeline.so"
exclude "lib/x86/libsmssdk.so"
exclude "lib/x86_64/libsmssdk.so"
exclude "lib/mips/libsmssdk.so"
exclude "lib/mips64/libqssq.so"
}

只保留armebi-v7a

1
2
3
4
5
6
7
8
9
packagingOptions {
exclude "lib/arm64-v8a/**"
exclude "lib/x86/**"
exclude "lib/armeabi/**"
exclude "lib/mips/**"
exclude "lib/mips64/**"
exclude "lib/x86_64/**"
}

这里只是演示排除非 armeabi-v7a 目录的so文件,除了排除so还可以排除资源文件哦!

统一协议标准跳转

1
2
3
manifestPlaceholders = [
APP_SCHEME: "xxx", //
]

xml对应代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<activity
android:name=".activity.EditUserInfoActivity"

android:screenOrientation="portrait">

<intent-filter>
<action android:name="android.intent.action.VIEW"></action>

<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>

<data
android:host="profile"
android:scheme="${APP_SCHEME}"></data>

</intent-filter>
</activity>

java对应代码

1
2
Intent intent=new Intent("xxx://profile");
startActivity(intent);

xml代码引用包名

1
2
3
4
5
6
7
8
9
10
11
```
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:grantUriPermissions="true"
android:exported="false">

<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_path" />
</provider>

多个源代码文件夹指定

1
2
3
4
5
6
7
8
9
10
11
12
 sourceSets {
main {
jniLibs.srcDirs = ['jniLibs']
res.srcDirs = [
'src/main/res',
'src/main/res_qssq'
]

}
}

sourceSets { main { jni.srcDirs = ['src/main/jni', 'src/main/jni/'] } }

这样以后如果某个模块不要了,删除图片和布局文件,操作速度也是非常快的.
编译生成版本号

编译修改app-release.apk为app应用名称-版本名-版本号.apk

网上有些方法实际上是有bug的,需要经常刷新,每次改版本的时候或者时间变化的时候需要重新build,我这个方法没有bug.

1
archivesBaseName = "情迁神器${versionName} build_${versionCode}".replace(' ', '_')

这个东西放到defaultConfig节点下即可.

debug包自动签名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
signingConfigs {
debug {
Properties properties = new Properties()
properties.load(project.rootProject.file('d:/sign/sign.properties').newDataInputStream())
def keyPwd = properties.getProperty("signingConfigs.keyPwd")
def keyName = properties.getProperty("signingConfigs.keyName")
def keyPath = properties.getProperty("signingConfigs.path")
storeFile file(keyPath)
storePassword keyPwd
keyAlias keyName
keyPassword keyPwd
v2SigningEnabled false
}


}

解决无法编译问题常见的几个配置

1
2
3
4
5
6
7
8
9
10
11
12
packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
}

lintOptions {
checkReleaseBuilds false
abortOnError false
}

让android studio debug模式编译多套so跑模拟器而打包则只编译v7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
buildTypes {
debug {

externalNativeBuild {
cmake {
cppFlags ""
abiFilters 'x86', 'armeabi-v7a'
}

//APP的build.gradle设置支持的SO库架构
}


}

生成arr到指定目录

1
2
3
4
5
6
7
8
9
10
11
12

libraryVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.aar')) {
def fileName = "${archivesBaseName}-${rootProject.version}-${variant.name}.aar"
output.outputFile = new File(outputFile.parent, fileName)
def folderName = rootProject.projectDir.toString() + new String("/arr-output")
output.outputFile = new File(folderName, fileName)
}
}
}

导入根目录文件夹的某个文件夹所有arr

1
2
3
flatDir{
dirs "${rootProject.projectDir}/arr_out"
}

取出不需要的资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
variantData.outputs.each {
def apFile = it.packageAndroidArtifactTask.getResourceFile();

it.packageAndroidArtifactTask.doFirst {
def arscFile = new File(apFile.parentFile, "resources.arsc");
JarUtil.extractZipEntry(apFile, "resources.arsc", arscFile);

def HashMap<String, ArrayList<DuplicatedEntry>> duplicatedResources = findDuplicatedResources(apFile);

removeZipEntry(apFile, "resources.arsc");

if (arscFile.exists()) {
FileInputStream arscStream = null;
ResourceFile resourceFile = null;
try {
arscStream = new FileInputStream(arscFile);

resourceFile = ResourceFile.fromInputStream(arscStream);
List<Chunk> chunks = resourceFile.getChunks();

HashMap<String, String> toBeReplacedResourceMap = new HashMap<String, String>(1024);

// 处理arsc并删除重复资源
Iterator<Map.Entry<String, ArrayList<DuplicatedEntry>>> iterator = duplicatedResources.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ArrayList<DuplicatedEntry>> duplicatedEntry = iterator.next();

// 保留第一个资源,其他资源删除掉
for (def index = 1; index < duplicatedEntry.value.size(); ++index) {
removeZipEntry(apFile, duplicatedEntry.value.get(index).name);

toBeReplacedResourceMap.put(duplicatedEntry.value.get(index).name, duplicatedEntry.value.get(0).name);
}
}

for (def index = 0; index < chunks.size(); ++index) {
Chunk chunk = chunks.get(index);
if (chunk instanceof ResourceTableChunk) {
ResourceTableChunk resourceTableChunk = (ResourceTableChunk) chunk;
StringPoolChunk stringPoolChunk = resourceTableChunk.getStringPool();
for (def i = 0; i < stringPoolChunk.stringCount; ++i) {
def key = stringPoolChunk.getString(i);
if (toBeReplacedResourceMap.containsKey(key)) {
stringPoolChunk.setString(i, toBeReplacedResourceMap.get(key));
}
}
}
}

} catch (IOException ignore) {
} catch (FileNotFoundException ignore) {
} finally {
if (arscStream != null) {
IOUtils.closeQuietly(arscStream);
}

arscFile.delete();
arscFile << resourceFile.toByteArray();

addZipEntry(apFile, arscFile);
}
}
}
}
通过这种方式可以有效减少重复资源

还有更多技巧欢迎吐槽哦!!!
更多参考推荐
http://blog.csdn.net/s402178946/article/details/54140200