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 方法设置的资源会在 R 文件生成对应的 id。
在 AndroidManifest.xml 中使用 authority 字符串
<provider android:name='com.facebook.FacebookContentProvider' android:authorities='@string/authority' android:exported='true' /> 替换 AndroidManifest.xml 中的占位符
使用 manifestPlaceholders 可以定义相关字段替换 AndroidManifest.xml 中的占位符。
格式:manifestPlaceholders = [ key1:'value1', key2:'value2', ... ]
下面是一个示例:
android { defaultConfig {def authorityName = 'com.linchaolong.android.app.droidplugin_stub'manifestPlaceholders = [ authorityName:'${authorityName}', key:'value',] }}
说明:manifestPlaceholders 是一个 map。
在 AndroidManifest.xml 中通过 ${key} 引用相关字段。
自定义 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 操作符可用于定义变量和函数。
在 java 代码中你可以通过 BuildConfig.key 访问对应的字段,比如: BuildConfig.AUTHORITY 访问 AUTHORITY 常量。
统一管理不同 module 依赖库的版本新建一个 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 添加如下配置应用 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'}
严重注意:引用 ext 中字段时要使用双引号,不能是单引号。格式为 ${key} 或 $key
建立各 Module 共享的配置比如,这里想统一设置各 Module 支持的 so 库架构,可以在工程目录下新建一个 module.gradle 存放共享的配置,配置如下:
// Module 共享的配置android { defaultConfig { ndk { //设置支持的SO库架构 abiFilters ’armeabi-v7a’ //, ’armeabi’ , ’x86’, ’x86_64’, ’arm64-v8a’ } }}
然后,在各 Module 下的 build.gradle 配置中应用 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)} } } }} 手动 build 工程
我们应该都或多或少遇到过这种情况,当我们第一次打开一个项目时,该项目会先下载相关的依赖项,如果很多的话,将会等很久,而且又不能做其他操作,这样太浪费时间了。

Image
下面说说如何在命令行中手动 build 工程:
每个 android studio 工程下应该都会有 gradlew.bat (Windows) 和 gradlew (Mac) 两个脚本文件,我们可以打开命令行,cd 到工程目录下,通过执行 gradlew.bat build 命令,手动去构建工程。

Image
通过在命令行构建工程可以不影响当前工作,而且构建完成后再使用 android studio 打开该工程将会比较快。
手动下载和替换本地 gradle/jarbuild 过程很慢?这个多数是由于个别依赖项下载速度过慢引起的,有时还会卡在某个点,但我们可以通过手动下载替换解决该问题。
这里分为两个部分,一个是 gradle 的下载替换,一个是依赖库的下载替换。
我们通过在命令行执行 gradlew.bat build 命令可以看到相关依赖的下载地址:

Paste_Image.png
正常下载速度可能只有几十KB(可能更低...),但是如果我们把下载链接 copy 到迅雷下载,它是这样的:

Paste_Image.png
在 windows 下,gradle 存放目录就在 C:Users用户名.gradlewrapperdists 下。下载完成后,把 *.lck 和 *.zip.part 文件删掉,替换为我们刚下载的 .zip 。

Paste_Image.png
重新执行 gradlew.bat build 命令可以看到它将会自动解压该 *.zip 文件。

Paste_Image.png
在 windows 下,依赖库的存放目录就在 C:Users用户名.gradlecaches 。jar文件的下载替换也是同理,比如我这里下载一个 common-25.3.0-alpha2.jar ,下载完成后把它放在 common-25.3.0-alpha2.pom 同级目录下,重新执行 build 命令即可。

Paste_Image.png
这里的目录路径可能和你的不太一样,可以使用 Everything 搜索一下文件名。
构建一个aar文件如果你的 module 声明为 android library(即在 build.gradle 文件中使用 apply plugin:’com.android.library’ ),它将在构建时输出 .aar 文件,在 module 的 build/outputs/aar 目录下。
你可以选择该 module ,然后 Build —> Make Module * 构建该 module。或者使用 gradlew.bat build 命令构建工程。然后就可以在输出目录下找到 .aar 文件了。

Paste_Image.png
引用 aar 文件假设把 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 目录,否则会找不到文件。
repositories { flatDir { dirs project(’:Library’).file(’libs’) }}
多个目录使用 “,” 分隔
快捷键由于 Android Studio 是基于 IDEA 的,所以很多快捷键是通用的。
全局替换Edit —> Find —> Replace in Path

Replace in Path
动态调试app1.在源码先打断点,点击挂接 Android 进程按钮。

Paste_Image.png
2.选择 app 进程,点OK,开始调试。

Paste_Image.png
一些好用的插件插件安装说明:
在线安装 打开 File ——> Settings ——> Plugins ——> Browse repositories... 搜索插件名,点 Install 下载安装,安装完成后重启生效。 离线安装 下载插件安装包,打开 File ——> Settings ——> Plugins ——> Install plugin from disk... 选择插件安装包,安装完成后重启生效。 GsonFormatGsonFormat 是一个可以快速将 JSON 字符串转换为 Entity 类的插件。

GsonFormat
使用说明: Alt + S 调出 GsonFormat,或者 Alt Insert + GsonFormat 。
在 Settings 中选择 filed(public) ,Enter 保存修改,可以只生成 public 字段,不生成一大堆的 getter 和 setter,代码会更简洁些。
插件地址: 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
使用说明:把光标停在 setContentView(R.layout.activity_settings) 那行中的 activity_settings 上右键选择 Generate ( alt + insert )→ Generate Butterknife Injections
注意:需要把光标停在 layout 的名称上才能调出 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
使用说明:选中要翻译的内容,选择 Edit ——> Translate 或者按下 command + I (我这里设置为 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.这是错误是因为应用的方法数已经超过了64K了,在 class 转换 dex 文件时报错了。一个 dex 文件的最大方法数是65536,所以这时候要启用 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]这种错误一般出现在打包的时候,表示 strings.xml 中缺失本地化的字符串资源。
这个错误有两个解决方案:
在 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' >
缺失的本地化字符串资源会使用默认字符串资源。
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 后启动出现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 尝试对你的代码执行热交换,导致 Application 类被移除所以出现 ClassNotFoundException。
停用 Instant Run, File --> Settings--> Build,Execution,Deployment -->Instant Run ---> 取消勾选 'Enable instant run'
相关文章 Intellij IDEA使用技巧整理 Android Studio各种快捷功能及好用的插件 tools 属性参考文档来自:https://juejin.im/entry/58bfd80ea22b9d00588c3444
相关文章:
1. Android Studio实现简单的通讯录2. Android Studio kotlin生成编辑类注释代码3. Android studio 混淆配置详解4. 解决Android Studio xml 格式化不自动换行的问题5. Android Studio 安装配置方法完整教程【小白秒懂】6. Android Studio 视频播放失败 start called in state1 异常怎么解决7. Python collections模块的使用技巧8. Android Studio常用插件9. Android Studio 创建自定义控件的方法10. Android Studio配置(Android Studio4.1为例)

网公网安备