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

此博停更,博客新地址

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

  • 原文地址:Little Things That Matter
  • 原文作者:Dmytro Danylyk
  • 译者 / 校对者:bincn

本文是配置 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,然后点击生成按钮。

【译文】配置 Android 项目系列1——小事情_第1张图片
gitignore_io.png

查看 template 项目的 gitignore 文件。

tools folder

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

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

【译文】配置 Android 项目系列1——小事情_第2张图片
tools_folder.png

通常我会放入自定义的 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.(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. 持续集成

你可能感兴趣的:(【译文】配置 Android 项目系列1——小事情)