说明:由于翻译水平有限,可能会存在一些不恰当的地方,欢迎指出,我会马上改正。系列的剩余部分会陆续翻译完。
- 原文地址:Little Things That Matter
- 原文作者:Dmytro Danylyk
- 译者 / 校对者:bincn
本文是配置 Android 项目系列的一部分:
我们在这篇文章中讨论的一切都可以在 template 项目中找到
gitignore
当你在 Android Studio 中创建一个新的 Android 项目时,它就已经生成了 gitignore 文件,但是通常并不包含所有必要的规则。
为了快速生成和下载 gitignore 文件,我推荐你使用 gitignore.io 网站。只要输入必要的关键词,例如 Android,Intellij,然后点击生成按钮。
查看 template 项目的 gitignore 文件。
tools folder
如果你有一些第三方脚本、规则集或者其他和你项目相关的文件,不要放在根目录下,会造成混乱。(特别是哪些使用项目视图,而不是 Android 视图)
尝试创建一个文件夹(例如:tools),并把这些文件放入这个文件夹。
通常我会放入自定义的 gradle 脚本文件、混淆 (proguard) 规则和静态代码分析工具,例如:pmd、findbugs、lint。
查看 template 项目的 tools 文件夹
flavors
Flavors 用于创建不同设置的构建。在大多数情况下,我会设置两种风格,它们的不同在于:
- applicationId
- versionCode / versionName
- server endpoints
- google services keys
- ...
productFlavors {
dev {
signingConfig signingConfigs.debug
versionCode gitVersionCodeTime
versionName gitVersionName
}
prod {
signingConfig signingConfigs.release
versionCode gitVersionCode
versionName gitVersionName
}
}
查看 template 项目的 productFlavors
keystore
密钥库是一个二进制文件,包含一个或多个私钥用于签名你的应用程序。
当你在 IDE 中运行或者调试项目,Android Studio 会通过 Android SDK 工具生成一个调试证书自动的签名你的 APK。
使用本地调试密钥库时有几个问题:
- 365天期满
- 通过多台电脑安装应用需要先卸载
- 谷歌的服务需要密钥库 SHA-1 指纹
这就是为什么我通常生成调试密钥库提交到版本控制系统。
signingConfigs {
debug {
keyAlias 'androiddebugkey'
keyPassword 'android'
storePassword 'android'
storeFile file('../keystore/debug.keystore')
}
release {
...
}
}
查看 template 项目的 signingConfigs
proguard
Android 上的混淆器用于三件事:
- 缩小未使用的代码,帮助你免于64K限制 (64k limit)
- 优化代码和 APK
- 混淆代码,使你的 APK 难逆向工程
问题是,混淆和代码优化显著增加编译时间,使调试更难。
这就是为什么最好是针对发布和调试构建使用不同的混淆器规则:
- rules-proguard.pro
- rules-proguard-debug.pro
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
"$project.rootDir/tools/rules-proguard.pro"
signingConfig signingConfigs.release
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
"$project.rootDir/tools/rules-proguard-debug.pro"
signingConfig signingConfigs.debug
}
}
对于调试构建,混淆器规则必须具备以下内容,强制忽略警告,跳过代码混淆与优化:
# Add project specific ProGuard rules here.
-dontobfuscate
-dontoptimize
-ignorewarnings
对于发布版本设置混淆器规则是很难的,因为几乎每一个库都会有它自己特定的规则。幸好有开源库 android-proguard-snippets,包含所有主要库的混淆规则。
# Add project specific ProGuard rules here.
# Remove logs
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
# Proguard configurations for common Android libraries:
# https://github.com/krschultz/android-proguard-snippets
查看 template 项目的 rules-proguard.pro 和 rules-proguard-debug.pro
strict mode
Android 的严格模式 (StrictMode) 帮助你检测不同种类的问题:
- 可以关闭的对象没有关闭
- 在主线程执行文件读取和网络请求
- 暴露 uri
- ...
每当检测到这样的问题,它可以显示适当的日志或让应用程序崩溃,这取决于你的配置。
我建议你在调试版本中打开它,并且使用 detectAll 方法检测各种问题。
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
}
以下是示例 log,当你忘记关闭 SQLiteCursor :
StrictMode:
A resource was acquired at attached stack trace but never released.
See java.io.Closeable for information on avoiding resource leaks.
java.lang.Throwable: Explicit termination method 'close' not called
at dalvik.system.CloseGuard.open(CloseGuard.java:184)
at android.database.CursorWindow.<init>(CursorWindow.java:111)
at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
at com.dd.template.MainActivity.onCreate(MainActivity.java:124)
查看 template 项目的 StrictMode
译文