Android Studio,使用技巧,問題記錄和一些好用的插件
比如在 production,development,qa 不同階段使用不同的 packageName 和 authority,在 build.gradle 中配置如下:
productFlavors {production { applicationId = 'com.myapp.app' resValue 'string', 'authority', 'com.facebook.app.FacebookContentProvider5435651423234'}development { applicationId = 'com.myapp.development' resValue 'string', 'authority', 'com.facebook.app.FacebookContentProvider2134564533421'}qa { applicationId = 'com.myapp.qa' resValue 'string', 'authority', 'com.facebook.app.FacebookContentProvider29831237981287319'}}
通過 resValue 方法設(shè)置的資源會(huì)在 R 文件生成對(duì)應(yīng)的 id。
在 AndroidManifest.xml 中使用 authority 字符串
<provider android:name='com.facebook.FacebookContentProvider' android:authorities='@string/authority' android:exported='true' /> 替換 AndroidManifest.xml 中的占位符
使用 manifestPlaceholders 可以定義相關(guān)字段替換 AndroidManifest.xml 中的占位符。
格式:manifestPlaceholders = [ key1:'value1', key2:'value2', ... ]
下面是一個(gè)示例:
android { defaultConfig {def authorityName = 'com.linchaolong.android.app.droidplugin_stub'manifestPlaceholders = [ authorityName:'${authorityName}', key:'value',] }}
說(shuō)明:manifestPlaceholders 是一個(gè) map。
在 AndroidManifest.xml 中通過 ${key} 引用相關(guān)字段。
自定義 BuildConfig 字段通過 buildConfigField 可以添加自定義的字段到 BuildConfig 中。
格式:buildConfigField 'type', 'key', 'value'
android { defaultConfig{def authority = 'com.linchaolong.android.app'buildConfigField 'String', 'AUTHORITY', ''${authority }''buildConfigField 'int', 'FOO', '42'buildConfigField 'String', 'FOO_STRING', ''foo''buildConfigField 'boolean', 'LOG', 'true' }}
def 操作符可用于定義變量和函數(shù)。
在 java 代碼中你可以通過 BuildConfig.key 訪問對(duì)應(yīng)的字段,比如: BuildConfig.AUTHORITY 訪問 AUTHORITY 常量。
統(tǒng)一管理不同 module 依賴庫(kù)的版本新建一個(gè) config.gradle 在工程根目錄下,并添加一些全局的配置:
allprojects {repositories { jcenter()}ext{ compileSdkVersion = 25 buildToolsVersion = '25.0.0' minSdkVersion = 14 targetSdkVersion = 25 support = ’25.0.0’ play_services = ’9.8.0’ rxjava = ’2.0.1’ // Json gson = ’2.8.0’ // HTTP okhttp = ’3.4.1’ retrofit = ’2.1.0’ glide = ’3.7.0’ // DEPS INJECTION dagger = ’2.6’ // VIEW INJECTION butterknife = ’8.4.0’ // DEBUG stetho = ’1.4.1’}}
然后在 project-level 下的 build.gradle 添加如下配置應(yīng)用 config.gradle :
apply from: rootProject.file(’config.gradle’)
在各 module 的 build.gradle 引用 ext 中的字段
在 android 塊中引用 ext 中的字段
android {compileSdkVersion project.ext.compileSdkVersionbuildToolsVersion project.ext.buildToolsVersiondefaultConfig { applicationId 'linchaolong.demo' minSdkVersion project.ext.minSdkVersion targetSdkVersion project.ext.targetSdkVersion def QQ_APPID = rootProject.ext.QQ_APPID manifestPlaceholders = [QQ_APPID:'${QQ_APPID}']}}
在 dependencies 塊下引用 ext 中的字段
dependencies {compile 'com.android.support:appcompat-v7:$support'// Debugcompile 'com.facebook.stetho:stetho:$stetho'compile 'com.facebook.stetho:stetho-okhttp3:$stetho'debugCompile 'com.facebook.stetho:stetho-js-rhino:$stetho'// Jsoncompile 'com.google.code.gson:gson:$gson'// Butterknifecompile 'com.jakewharton:butterknife:$butterknife'annotationProcessor 'com.jakewharton:butterknife-compiler:$butterknife'// RxJavacompile 'io.reactivex.rxjava2:rxjava:$rxjava'compile 'io.reactivex.rxjava2:rxandroid:$rxjava'}
嚴(yán)重注意:引用 ext 中字段時(shí)要使用雙引號(hào),不能是單引號(hào)。格式為 ${key} 或 $key
建立各 Module 共享的配置比如,這里想統(tǒng)一設(shè)置各 Module 支持的 so 庫(kù)架構(gòu),可以在工程目錄下新建一個(gè) module.gradle 存放共享的配置,配置如下:
// Module 共享的配置android { defaultConfig { ndk { //設(shè)置支持的SO庫(kù)架構(gòu) abiFilters ’armeabi-v7a’ //, ’armeabi’ , ’x86’, ’x86_64’, ’arm64-v8a’ } }}
然后,在各 Module 下的 build.gradle 配置中應(yīng)用 module.gradle,示例如下:
apply plugin: ’com.android.application’apply from: rootProject.file(’module.gradle’) 自定義 release apk 名稱
修改 build.gradle 配置如下:
android { buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile(’proguard-android.txt’), ’proguard-rules.pro’ signingConfig signingConfigs.release // 自定義 release apk 名稱 applicationVariants.all { variant ->variant.outputs.each { output -> def releaseTime = new Date().format(’yyyyMMddHHmmss’) // 修改 release apk 名稱,app_1.0_20170108224145.apk def fileName = output.outputFile.name.replace('-release', '_${defaultConfig.versionName}_'+releaseTime) output.outputFile = new File(output.outputFile.parent, fileName)} } } }} 手動(dòng) build 工程
我們應(yīng)該都或多或少遇到過這種情況,當(dāng)我們第一次打開一個(gè)項(xiàng)目時(shí),該項(xiàng)目會(huì)先下載相關(guān)的依賴項(xiàng),如果很多的話,將會(huì)等很久,而且又不能做其他操作,這樣太浪費(fèi)時(shí)間了。
Image
下面說(shuō)說(shuō)如何在命令行中手動(dòng) build 工程:
每個(gè) android studio 工程下應(yīng)該都會(huì)有 gradlew.bat (Windows) 和 gradlew (Mac) 兩個(gè)腳本文件,我們可以打開命令行,cd 到工程目錄下,通過執(zhí)行 gradlew.bat build 命令,手動(dòng)去構(gòu)建工程。
Image
通過在命令行構(gòu)建工程可以不影響當(dāng)前工作,而且構(gòu)建完成后再使用 android studio 打開該工程將會(huì)比較快。
手動(dòng)下載和替換本地 gradle/jarbuild 過程很慢?這個(gè)多數(shù)是由于個(gè)別依賴項(xiàng)下載速度過慢引起的,有時(shí)還會(huì)卡在某個(gè)點(diǎn),但我們可以通過手動(dòng)下載替換解決該問題。
這里分為兩個(gè)部分,一個(gè)是 gradle 的下載替換,一個(gè)是依賴庫(kù)的下載替換。
我們通過在命令行執(zhí)行 gradlew.bat build 命令可以看到相關(guān)依賴的下載地址:
Paste_Image.png
正常下載速度可能只有幾十KB(可能更低...),但是如果我們把下載鏈接 copy 到迅雷下載,它是這樣的:
Paste_Image.png
在 windows 下,gradle 存放目錄就在 C:Users用戶名.gradlewrapperdists 下。下載完成后,把 *.lck 和 *.zip.part 文件刪掉,替換為我們剛下載的 .zip 。
Paste_Image.png
重新執(zhí)行 gradlew.bat build 命令可以看到它將會(huì)自動(dòng)解壓該 *.zip 文件。
Paste_Image.png
在 windows 下,依賴庫(kù)的存放目錄就在 C:Users用戶名.gradlecaches 。jar文件的下載替換也是同理,比如我這里下載一個(gè) common-25.3.0-alpha2.jar ,下載完成后把它放在 common-25.3.0-alpha2.pom 同級(jí)目錄下,重新執(zhí)行 build 命令即可。
Paste_Image.png
這里的目錄路徑可能和你的不太一樣,可以使用 Everything 搜索一下文件名。
構(gòu)建一個(gè)aar文件如果你的 module 聲明為 android library(即在 build.gradle 文件中使用 apply plugin:’com.android.library’ ),它將在構(gòu)建時(shí)輸出 .aar 文件,在 module 的 build/outputs/aar 目錄下。
你可以選擇該 module ,然后 Build —> Make Module * 構(gòu)建該 module。或者使用 gradlew.bat build 命令構(gòu)建工程。然后就可以在輸出目錄下找到 .aar 文件了。
Paste_Image.png
引用 aar 文件假設(shè)把 aar 文件放在 module 下的 libs 目錄。
Paste_Image.png
引用本 module 的 aar 文件 build.gradle 配置如下:
repositories{ flatDir{ dirs ’libs’ }}dependencies { compile(name:’stetho_realm-release’, ext:’aar’)}
如果是引用其他 module 的 aar 文件,還要在本 module 的 build.gradle 中配置被引用 module 的 aar 目錄,否則會(huì)找不到文件。
repositories { flatDir { dirs project(’:Library’).file(’libs’) }}
多個(gè)目錄使用 “,” 分隔
快捷鍵由于 Android Studio 是基于 IDEA 的,所以很多快捷鍵是通用的。
全局替換Edit —> Find —> Replace in Path
Replace in Path
動(dòng)態(tài)調(diào)試app1.在源碼先打斷點(diǎn),點(diǎn)擊掛接 Android 進(jìn)程按鈕。
Paste_Image.png
2.選擇 app 進(jìn)程,點(diǎn)OK,開始調(diào)試。
Paste_Image.png
一些好用的插件插件安裝說(shuō)明:
在線安裝 打開 File ——> Settings ——> Plugins ——> Browse repositories... 搜索插件名,點(diǎn) Install 下載安裝,安裝完成后重啟生效。 離線安裝 下載插件安裝包,打開 File ——> Settings ——> Plugins ——> Install plugin from disk... 選擇插件安裝包,安裝完成后重啟生效。 GsonFormatGsonFormat 是一個(gè)可以快速將 JSON 字符串轉(zhuǎn)換為 Entity 類的插件。
GsonFormat
使用說(shuō)明: Alt + S 調(diào)出 GsonFormat,或者 Alt Insert + GsonFormat 。
在 Settings 中選擇 filed(public) ,Enter 保存修改,可以只生成 public 字段,不生成一大堆的 getter 和 setter,代碼會(huì)更簡(jiǎn)潔些。
插件地址: https://plugins.jetbrains.com/idea/plugin/7654-gsonformat
Github地址: https://github.com/zzz40500/GsonFormat
Android ButterKnife ZeleznyAndroid ButterKnife Zelezny 是 Android 下的注解框架 ButterKnife 的輔助插件,用于一鍵生成 Butterknife 視圖注入代碼。
Android ButterKnife Zelezny
使用說(shuō)明:把光標(biāo)停在 setContentView(R.layout.activity_settings) 那行中的 activity_settings 上右鍵選擇 Generate ( alt + insert )→ Generate Butterknife Injections
注意:需要把光標(biāo)停在 layout 的名稱上才能調(diào)出 ButterKnife Zelezny 。
ButterKnife: https://github.com/JakeWharton/butterknife
插件地址: https://plugins.jetbrains.com/idea/plugin/7369-android-butterknife-zelezny
Github地址: https://github.com/avast/android-butterknife-zelezny
ECTranslationAndroid Studio 翻譯插件,可以將英文翻譯為中文。
ECTranslation
使用說(shuō)明:選中要翻譯的內(nèi)容,選擇 Edit ——> Translate 或者按下 command + I (我這里設(shè)置為 Shift + I )。
修改快捷鍵: Preferences -> Keymap -> 搜索Translate - > 右鍵 add Keyboard Shortcut . 輸入你想要的快捷鍵即可。
插件地址: https://plugins.jetbrains.com/idea/plugin/8469-ectranslation
Github地址: https://github.com/Skykai521/ECTranslation
問題記錄 Error:The number of method references in a .dex file cannot exceed 64K.這是錯(cuò)誤是因?yàn)閼?yīng)用的方法數(shù)已經(jīng)超過了64K了,在 class 轉(zhuǎn)換 dex 文件時(shí)報(bào)錯(cuò)了。一個(gè) dex 文件的最大方法數(shù)是65536,所以這時(shí)候要啟用 Multidex。
1.app 的 build.gradle 添加如下配置
android { defaultConfig {// 啟用 multidex 支持.multiDexEnabled true }}dependencies { compile ’com.android.support:multidex:1.0.1’}
2.在 AndroidManifest.xml 下配置 MultiDexApplication
<?xml version='1.0' encoding='utf-8'?><manifest xmlns:android='http://schemas.android.com/apk/res/android' package='com.example.android.multidex.myapplication'> <application...android:name='android.support.multidex.MultiDexApplication'>... </application></manifest>
如果是自定義了 Application 則讓其繼承 MultiDexApplication。
官方文檔: https://developer.android.com/tools/building/multidex.html
Error: '*' is not translated in 'en' (English) [MissingTranslation]這種錯(cuò)誤一般出現(xiàn)在打包的時(shí)候,表示 strings.xml 中缺失本地化的字符串資源。
這個(gè)錯(cuò)誤有兩個(gè)解決方案:
在 valuesstrings.xml 或出問題的 strings.xml 中添加如下配置:<resources xmlns:tools='http://schemas.android.com/tools' tools:locale='en'> 在 valuesstrings.xml 或出問題的 strings.xml 中添加如下配置:
<resources xmlns:tools='http://schemas.android.com/tools' tools:ignore='MissingTranslation' >
缺失的本地化字符串資源會(huì)使用默認(rèn)字符串資源。
Could not find Library日志如下:
Error:A problem occurred configuring project ’:app’.> Could not resolve all dependencies for configuration ’:app:_debugCompile’. > Could not find com.android.support:appcompat-v7:22.2.0. Searched in the following locations: https://jcenter.bintray.com/com/android/support/appcompat-v7/22.2.0/appcompat-v7-22.2.0.pom https://jcenter.bintray.com/com/android/support/appcompat-v7/22.2.0/appcompat-v7-22.2.0.jar file:/D:/AndroidDeveloper/adt-bundle-windows-x86-20130917/sdk/extras/google/m2repository/com/android/support/appcompat-v7/22.2.0/appcompat-v7-22.2.0.pom file:/D:/AndroidDeveloper/adt-bundle-windows-x86-20130917/sdk/extras/google/m2repository/com/android/support/appcompat-v7/22.2.0/appcompat-v7-22.2.0.jar Required by: HelloWorld:app:unspecified
解決辦法:更新你的 Android Support Library 和 Android Support Repository.
修改 applicationId 后啟動(dòng)出現(xiàn)ClassNotFoundException日志如下:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.linchaolong.android.app, PID: 10690 java.lang.RuntimeException: Unable to instantiate application com.android.tools.fd.runtime.BootstrapApplication: java.lang.IllegalStateException: java.lang.ClassNotFoundException: com.linchaolong.android.app.MyApplication at android.app.LoadedApk.makeApplication(LoadedApk.java:565) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4545) at android.app.ActivityThread.access$1500(ActivityThread.java:154) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1369) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5275) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) Caused by: java.lang.IllegalStateException: java.lang.ClassNotFoundException: com.linchaolong.demo.App at com.android.tools.fd.runtime.BootstrapApplication.createRealApplication(BootstrapApplication.java:220) at com.android.tools.fd.runtime.BootstrapApplication.attachBaseContext(BootstrapApplication.java:239) at android.app.Application.attach(Application.java:185) at android.app.Instrumentation.newApplication(Instrumentation.java:996) at android.app.Instrumentation.newApplication(Instrumentation.java:980) at android.app.LoadedApk.makeApplication(LoadedApk.java:560) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4545)at android.app.ActivityThread.access$1500(ActivityThread.java:154)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1369)at android.os.Handler.dispatchMessage(Handler.java:102)at android.os.Looper.loop(Looper.java:135)at android.app.ActivityThread.main(ActivityThread.java:5275)at java.lang.reflect.Method.invoke(Native Method)at java.lang.reflect.Method.invoke(Method.java:372)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) Caused by: java.lang.ClassNotFoundException: com.linchaolong.android.app.MyApplication at java.lang.Class.classForName(Native Method) at java.lang.Class.forName(Class.java:306) at java.lang.Class.forName(Class.java:270) at com.android.tools.fd.runtime.BootstrapApplication.createRealApplication(BootstrapApplication.java:209) at com.android.tools.fd.runtime.BootstrapApplication.attachBaseContext(BootstrapApplication.java:239)at android.app.Application.attach(Application.java:185)at android.app.Instrumentation.newApplication(Instrumentation.java:996)at android.app.Instrumentation.newApplication(Instrumentation.java:980)at android.app.LoadedApk.makeApplication(LoadedApk.java:560)at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4545)at android.app.ActivityThread.access$1500(ActivityThread.java:154)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1369)at android.os.Handler.dispatchMessage(Handler.java:102)at android.os.Looper.loop(Looper.java:135)at android.app.ActivityThread.main(ActivityThread.java:5275)at java.lang.reflect.Method.invoke(Native Method)at java.lang.reflect.Method.invoke(Method.java:372)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) Caused by: java.lang.ClassNotFoundException: Didn’t find class 'com.linchaolong.android.app.MyApplication' on path: DexPathList[[zip file
原因是 Android Studio 的 Instant Run 嘗試對(duì)你的代碼執(zhí)行熱交換,導(dǎo)致 Application 類被移除所以出現(xiàn) ClassNotFoundException。
停用 Instant Run, File --> Settings--> Build,Execution,Deployment -->Instant Run ---> 取消勾選 'Enable instant run'
相關(guān)文章 Intellij IDEA使用技巧整理 Android Studio各種快捷功能及好用的插件 tools 屬性參考文檔來(lái)自:https://juejin.im/entry/58bfd80ea22b9d00588c3444
相關(guān)文章:
1. Android studio 自動(dòng)換行和取消自動(dòng)換行操作2. 解決Android studio xml界面無(wú)法預(yù)覽問題3. 開發(fā)效率翻倍的Web API使用技巧4. 使用Android Studio實(shí)現(xiàn)為系統(tǒng)級(jí)的app簽名5. Android Studio 創(chuàng)建自定義控件的方法6. Android打包篇:Android Studio將代碼打包成jar包教程7. Android Studio用genymotion運(yùn)行后小圖標(biāo)無(wú)法顯示問題8. Android Studio修改Log信息顏色的實(shí)現(xiàn)9. 淺談Android studio 生成apk文件時(shí)的 key store path 的問題10. Android studio設(shè)置指定的簽名文件教程
