【譯文】配置 Android 項目系列1——小事情

說明:由于翻譯水平有限,可能會存在一些不恰當(dāng)?shù)牡胤?,歡迎指出,我會馬上改正。系列的剩余部分會陸續(xù)翻譯完。

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

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

我們在這篇文章中討論的一切都可以在 template 項目中找到

gitignore

當(dāng)你在 Android Studio 中創(chuàng)建一個新的 Android 項目時,它就已經(jīng)生成了 gitignore 文件,但是通常并不包含所有必要的規(guī)則。

為了快速生成和下載 gitignore 文件,我推薦你使用 gitignore.io 網(wǎng)站。只要輸入必要的關(guān)鍵詞,例如 Android,Intellij,然后點擊生成按鈕。

gitignore_io.png

查看 template 項目的 gitignore 文件。

tools folder

如果你有一些第三方腳本、規(guī)則集或者其他和你項目相關(guān)的文件,不要放在根目錄下,會造成混亂。(特別是哪些使用項目視圖,而不是 Android 視圖)

嘗試創(chuàng)建一個文件夾(例如:tools),并把這些文件放入這個文件夾。

tools_folder.png

通常我會放入自定義的 gradle 腳本文件、混淆 (proguard) 規(guī)則和靜態(tài)代碼分析工具,例如:pmd、findbugslint。

查看 template 項目的 tools 文件夾

flavors

Flavors 用于創(chuàng)建不同設(shè)置的構(gòu)建。在大多數(shù)情況下,我會設(shè)置兩種風(fēng)格,它們的不同在于:

  • 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

密鑰庫是一個二進制文件,包含一個或多個私鑰用于簽名你的應(yīng)用程序。

當(dāng)你在 IDE 中運行或者調(diào)試項目,Android Studio 會通過 Android SDK 工具生成一個調(diào)試證書自動的簽名你的 APK。

使用本地調(diào)試密鑰庫時有幾個問題:

  • 365天期滿
  • 通過多臺電腦安裝應(yīng)用需要先卸載
  • 谷歌的服務(wù)需要密鑰庫 SHA-1 指紋

這就是為什么我通常生成調(diào)試密鑰庫提交到版本控制系統(tǒng)。

signingConfigs {
   debug {
       keyAlias 'androiddebugkey'
       keyPassword 'android'
       storePassword 'android'
       storeFile file('../keystore/debug.keystore')
   }
   release {
       ...
   }
} 

查看 template 項目的 signingConfigs

proguard

Android 上的混淆器用于三件事:

  • 縮小未使用的代碼,幫助你免于64K限制 (64k limit)
  • 優(yōu)化代碼和 APK
  • 混淆代碼,使你的 APK 難逆向工程

問題是,混淆和代碼優(yōu)化顯著增加編譯時間,使調(diào)試更難。

這就是為什么最好是針對發(fā)布和調(diào)試構(gòu)建使用不同的混淆器規(guī)則:

  • 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
    }
}

對于調(diào)試構(gòu)建,混淆器規(guī)則必須具備以下內(nèi)容,強制忽略警告,跳過代碼混淆與優(yōu)化:

# Add project specific ProGuard rules here.
-dontobfuscate
-dontoptimize
-ignorewarnings

對于發(fā)布版本設(shè)置混淆器規(guī)則是很難的,因為幾乎每一個庫都會有它自己特定的規(guī)則。幸好有開源庫 android-proguard-snippets,包含所有主要庫的混淆規(guī)則。

# 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 的嚴(yán)格模式 (StrictMode) 幫助你檢測不同種類的問題:

  • 可以關(guān)閉的對象沒有關(guān)閉
  • 在主線程執(zhí)行文件讀取和網(wǎng)絡(luò)請求
  • 暴露 uri
  • ...

每當(dāng)檢測到這樣的問題,它可以顯示適當(dāng)?shù)娜罩净蜃寫?yīng)用程序崩潰,這取決于你的配置。

我建議你在調(diào)試版本中打開它,并且使用 detectAll 方法檢測各種問題。

if (BuildConfig.DEBUG) {
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .build());
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .build());
}

以下是示例 log,當(dāng)你忘記關(guān)閉 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. 靜態(tài)代碼分析工具
  4. 持續(xù)集成
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容