【译文】配置 Android 项目系列1——小事情

说明:由于翻译水平有限,可能会存在一些不恰当的地方,欢迎指出,我会马上改正。系列的剩余部分会陆续翻译完。

本文是配置 Android 项目系列的一部分:

  1. Little Things That Matter
  2. Version Name & Code
  3. Static Code Analyses Tools
  4. Continuous Integration

我们在这篇文章中讨论的一切都可以在 template 项目中找到

gitignore

当你在 Android Studio 中创建一个新的 Android 项目时,它就已经生成了 gitignore 文件,但是通常并不包含所有必要的规则。

为了快速生成和下载 gitignore 文件,我推荐你使用 gitignore.io 网站。只要输入必要的关键词,例如 Android,Intellij,然后点击生成按钮。

gitignore_io.png

查看 template 项目的 gitignore 文件。

tools folder

如果你有一些第三方脚本、规则集或者其他和你项目相关的文件,不要放在根目录下,会造成混乱。(特别是哪些使用项目视图,而不是 Android 视图)

尝试创建一个文件夹(例如:tools),并把这些文件放入这个文件夹。

tools_folder.png

通常我会放入自定义的 gradle 脚本文件、混淆 (proguard) 规则和静态代码分析工具,例如:pmdfindbugslint

查看 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.prorules-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

译文

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

推荐阅读更多精彩内容