前言
前段時(shí)間重拾安卓開發(fā),基于 IntelliJ IDEA 搭建了開發(fā)環(huán)境,整體體驗(yàn)還不錯(cuò),就記錄下我的配置過程。
本來想寫在 IntelliJ IDEA 插件和經(jīng)驗(yàn)分享 一文中,結(jié)果發(fā)現(xiàn)篇幅太長(zhǎng)了就單獨(dú)拎出來。
為什么不是 Android Studio ?
很久以前在同事的電腦上瞥過幾眼 Android Studio 的界面,有點(diǎn)丑陋而且看著不太好用的樣子。當(dāng)然,這不是主要原因,作為廣大網(wǎng)友強(qiáng)烈推薦的安卓開發(fā)工具必然有它的獨(dú)到之處,而我選擇 IntelliJ IDEA 也是有我的考量:
-
Android Studio 本來就是基于 IntelliJ IDEA 定制的( 后者 + 一堆定制插件 )。
對(duì)比了 Android Studio ( Arctic Fox | 2020.3.1 ) 和 IntelliJ IDEA ( 2021.3 ) 之后,發(fā)現(xiàn)二者的界面功能就是一個(gè)模子刻出來的,而屬于前者獨(dú)有的功能:
- 免費(fèi) 。
- C/C++ 語(yǔ)言、 CMake 、 NDK 支持。
- Jetpack Compose 支持。
-
Gradle 文件創(chuàng)建模板(
Gradle Build Script
)。 - 內(nèi)置對(duì) Google Cloud Platform 的支持,可輕松集成 Google Cloud Messaging 和 App Engine 。
- 其他功能:
我在 IntelliJ IDEA 上安裝了很多插件并做了較多配置,不想再重復(fù)一遍。而且能共用一個(gè) IDE 也能節(jié)省很多磁盤空間。
我在 IntelliJ IDEA 上本來就做多種語(yǔ)言的開發(fā): 前端 、 Java 后端 、 腳本語(yǔ)言( Bat / Shell / Python ) 等,能多一個(gè)安卓那自然是更好的。
理論上這個(gè)方案是沒問題的,我實(shí)際開發(fā)也還沒遇到過因?yàn)?IntelliJ IDEA 自身原因?qū)е碌膯栴}。所以,不要無(wú)腦聽別人說用什么就用什么,有疑惑就多試試。團(tuán)隊(duì)開發(fā)中,沒能力還是建議使用團(tuán)隊(duì)統(tǒng)一的 IDE 。
配置環(huán)境變量
開發(fā)時(shí)下載的依賴包、緩存、臨時(shí)配置等默認(rèn)是保存在用戶目錄( ${user.home} )下,通過配置環(huán)境變量可以將它們安排在自定義的目錄下。
# 設(shè)置 Android SDK 安裝目錄的路徑
# ref: https://developer.android.google.cn/studio/command-line/variables?hl=en
ANDROID_SDK_ROOT=E:\Android\SDK
# ANDROID_HOME 也指向 SDK 安裝目錄,但已棄用,只是為了兼容 AGP < 3.4.0
ANDROID_HOME=%ANDROID_SDK_ROOT%
# 注意和 ANDROID_SDK_ROOT 的區(qū)別,一般這個(gè)變量代表安卓模擬器配置文件目錄的父目錄
# adb 估計(jì)寫死了路徑, ${user.home}/.android/adbkey 無(wú)法根據(jù)這個(gè)變量遷移
# 按英文版文檔說明:Android Studio 4.2 起這個(gè)變量被 ANDROID_PREFS_ROOT 代替
ANDROID_SDK_HOME=E:\Android
# 修改 Gradle 的全局配置和緩存的目錄,IntelliJ IDEA 能夠自動(dòng)識(shí)別這個(gè)路徑
GRADLE_USER_HOME=E:\Android\.gradle
# 將 adb 加入到系統(tǒng)全局路徑中
Path=%ANDROID_SDK_ROOT%\platform-tools;%Path%
配置 Gradle
添加 Gradle 全局 初始化腳本 ,它們會(huì)在所有項(xiàng)目構(gòu)建開始前執(zhí)行,并可以對(duì)構(gòu)建生命周期進(jìn)行攔截,可以添加額外的配置和插件以及任務(wù)。( 參考 )
- 管理公司內(nèi)部的配置,例如去哪里查找定制的插件。
- 配置一些基于當(dāng)前環(huán)境( 開發(fā)環(huán)境還是持續(xù)集成環(huán)境 )的屬性。
- 提供構(gòu)建所需要的用戶個(gè)人信息,例如倉(cāng)庫(kù)或數(shù)據(jù)庫(kù)的用戶名和密碼。
- 定義機(jī)器的環(huán)境,例如 JDK 安裝在什么位置。
- 注冊(cè)一些監(jiān)聽器。這對(duì)一些需要監(jiān)聽 Gradle 事件的工具來說很有用。
- 注冊(cè)一些 Logger 。你可能希望去自定義如何輸出 Gradle 產(chǎn)生的日志信息。
下面所有腳本( 按需添加 )采用 Kotlin DSL 語(yǔ)法編寫, Gradle 5.0 起可用,如使用舊版本請(qǐng)自行改為 Groovy 語(yǔ)法。
沒有代碼提示的話,寫 Gradle 腳本比批處理還惡心。
在 Gradle 項(xiàng)目中打開下面的腳本才會(huì)有代碼提示。
-
.gradle/init.d/0.repos.init.gradle.kts
/* * 國(guó)內(nèi)的網(wǎng)絡(luò)環(huán)境默認(rèn)不設(shè)置鏡像加速的話很大概率無(wú)法下載依賴包導(dǎo)致初始化報(bào)錯(cuò),對(duì)于剛?cè)腴T的新手來說直接勸退。 * * 本腳本全局配置所有項(xiàng)目使用阿里云鏡像源進(jìn)行加速,這樣就不用每個(gè)項(xiàng)目重復(fù)設(shè)置了,新項(xiàng)目拉下來就能跑。 * * 文件名以 0 開頭是為了把這個(gè)腳本的執(zhí)行順序排在前面。 * * gradlew showRepos * gradlew switchDeleteRawRepos * * @author anyesu <https://github.com/anyesu> */ val pluginRepositories = ArrayList<MavenArtifactRepository>() val CONFIG_FILE = File(gradleUserHomeDir, "init.d/.deleteRawRepos") /** 是否刪除項(xiàng)目中配置的源地址 */ var deleteRawRepos = CONFIG_FILE.exists() val GROUP_NAME = "init.gradle" val TASK_NAME_SHOW_REPOS = "showRepos" val TASK_NAME_SWITCH_DELETE_RAW_REPOS = "switchDeleteRawRepos" // 源地址 val rawRepos = listOf( // central "https://repo1.maven.org/maven2/", "https://repo.maven.apache.org/maven2/", // jcenter "https://jcenter.bintray.com/", // google "https://maven.google.com/", "https://dl.google.com/dl/android/maven2/", // gradle-plugin "https://plugins.gradle.org/m2/" ) // 代理地址 object Repos { const val MAVEN_ALIYUN = "https://maven.aliyun.com/repository/public" const val MAVEN_JITPACK = "https://www.jitpack.io" const val GOOGLE_ALIYUN = "https://maven.aliyun.com/repository/google" const val GRADLE_PLUGIN_ALIYUN = "https://maven.aliyun.com/repository/gradle-plugin" const val GRADLE_PLUGIN_ALIYUN_OLD = "https://maven.aliyun.com/nexus/content/repositories/gradle-plugin" } projectsLoaded { allprojects { if (deleteRawRepos) deleteRawRepos() configureRepos() tasks.register(TASK_NAME_SHOW_REPOS) { group = GROUP_NAME description = "查看當(dāng)前項(xiàng)目最終依賴的倉(cāng)庫(kù)" doLast { printRepositories() } } } rootProject { tasks.named(TASK_NAME_SHOW_REPOS) { doFirst { displayScriptConfigs() pluginRepositories.print("pluginManagement.repositories") } } tasks.register(TASK_NAME_SWITCH_DELETE_RAW_REPOS) { group = GROUP_NAME description = "切換 - 是否刪除項(xiàng)目中配置的源地址" doLast { if (deleteRawRepos) CONFIG_FILE.delete() else CONFIG_FILE.createNewFile() deleteRawRepos = !deleteRawRepos displayScriptConfigs() } } } } beforeSettings { configurePluginManagement() } fun displayScriptConfigs() { println("[ Current Initialization Script Configs ]") println(" - deleteRawRepos [${if (deleteRawRepos) "enabled" else "disabled"}]") } fun Settings.configurePluginManagement() = pluginManagement { repositories { all { if (this !is MavenArtifactRepository) return@all if (!deleteRawRepos) { pluginRepositories.add(this) return@all } val path = url.toString().run { if (endsWith("/")) this else "$this/" } if (rawRepos.contains(path)) { logger.info("removed from `settings.pluginManagement.repositories`: ${display()}") remove(this) } else { pluginRepositories.add(this) } } // TODO 阿里云插件新版地址有時(shí)候 jar 會(huì)下載不下來,所以同時(shí)加上舊版的地址備用。 maven(Repos.GRADLE_PLUGIN_ALIYUN_OLD) maven(Repos.GRADLE_PLUGIN_ALIYUN) } } fun Project.configureRepos() { buildscript.repositories.configureRepos() repositories.configureRepos() } fun Project.deleteRawRepos() { buildscript.repositories.deleteRawRepos(name, "buildscript.repositories") repositories.deleteRawRepos(name, "repositories") } fun Project.printRepositories() { buildscript.repositories.print("buildscript.repositories") repositories.print("repositories") } fun RepositoryHandler.deleteRawRepos(projectName: String = "", display: String = "") { // TODO: all 的邏輯不僅順序執(zhí)行還會(huì)作為回調(diào) all { if (this is MavenArtifactRepository && rawRepos.contains(url.toString())) { logger.info("removed from `${projectName}.${display}`: ${display()}") remove(this) } } } fun RepositoryHandler.configureRepos() { mavenLocal() mavenCentral { url = uri(Repos.MAVEN_ALIYUN) } maven(Repos.MAVEN_ALIYUN) google { url = uri(Repos.GOOGLE_ALIYUN) } maven(Repos.MAVEN_JITPACK) jcenter { url = uri(Repos.MAVEN_ALIYUN) } if (!deleteRawRepos) { mavenCentral() google() jcenter() } } fun RepositoryHandler.mavenArtifactRepositories() = map { if (it is MavenArtifactRepository) it else null }.filterNotNull() fun RepositoryHandler.print(display: String = "") { mavenArtifactRepositories().print(display) } fun List<MavenArtifactRepository>.print(display: String = "") { println("\n[ ${display} ]") forEach { println(" - ${it.display()}") } } fun MavenArtifactRepository.display() = "[ ${name.padEnd(32)} ] -> $url"
-
.gradle/init.d/cacheToLocalMavenRepository.init.gradle.kts
解決了原腳本的幾個(gè)問題:
-
parts[1] 可能包含
.
,不能將其替換為/
,比如:org.jetbrains.intellij/org.jetbrains.intellij.gradle.plugin
-
還要考慮更深的子目錄,比如:
com.jetbrains.intellij.idea/ideaIC/2021.1.3/fef2d88b0f4771ce5ac9a9963d3717080439cf4f/ideaIC-2021.1.3
/* * 添加一個(gè) Task 用來把 Gradle 緩存的 Jar 包復(fù)制到 Maven 的本地倉(cāng)庫(kù),這樣和 Maven 就可以共用緩存了,而且 Maven 的目錄結(jié)構(gòu)更方便查找。 * * 需要先設(shè)置環(huán)境變量 M2_HOME 為 Maven 的安裝目錄,否則會(huì)復(fù)制到默認(rèn)的 ${user.home}/.m2 目錄。 * * 需要手動(dòng)執(zhí)行, Gradle 原有緩存在遷移后自行手動(dòng)刪除。 * * gradlew cacheToLocalMavenRepository * * @see https://blog.csdn.net/feinifi/article/details/81458639 * * @author anyesu <https://github.com/anyesu> */ val GROUP_NAME = "init.gradle" projectsLoaded { rootProject { tasks.register<Copy>("cacheToLocalMavenRepository") { group = GROUP_NAME description = "Gradle 緩存復(fù)制到 Maven 本地倉(cāng)庫(kù)" from(File(gradleUserHomeDir, "caches/modules-2/files-2.1")) into(repositories.mavenLocal().url) eachFile { val parts = ArrayList(path.split("/")) parts[0] = parts[0].replace('.', '/') // 路徑分割 if (parts.size > 3) parts.removeAt(3) // 去除隨機(jī)值 path = parts.joinToString("/") } duplicatesStrategy = DuplicatesStrategy.EXCLUDE // 重復(fù)文件策略 includeEmptyDirs = false } } }
-
-
.gradle/init.d/dependency-graph.init.gradle.kts
/* * 為所有項(xiàng)目添加 gradle-dependency-graph-generator-plugin 插件,用于生成項(xiàng)目的依賴關(guān)系圖。 * * gradlew generateDependencyGraph * gradlew generateProjectDependencyGraph * * @author anyesu <https://github.com/anyesu> */ val PLUGIN_ID = "com.vanniktech.dependency.graph.generator" projectsLoaded { allprojects { buildscript { repositories { mavenCentral() } dependencies { classpath("com.vanniktech:gradle-dependency-graph-generator-plugin:+") } } afterEvaluate { // 和項(xiàng)目配置沖突,如果項(xiàng)目中已經(jīng)配置了就忽略本配置 if (!plugins.hasPlugin(PLUGIN_ID)) { apply(plugin = PLUGIN_ID) logger.info("project '$name' apply plugin: $PLUGIN_ID") } } } }
-
.gradle/init.d/dependencyUpdates.init.gradle.kts
借助 Package Search 插件可以提供類似的功能,更直觀。
/* * 依賴版本管理,查看哪些依賴可以升級(jí)( 可自定義升級(jí)規(guī)則 )。 * * gradlew dependencyUpdates * * @see https://github.com/ben-manes/gradle-versions-plugin#using-a-gradle-init-script * * @author anyesu <https://github.com/anyesu> */ import com.github.benmanes.gradle.versions.VersionsPlugin import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask val GROUP_NAME = "init.gradle" val PLUGIN_ID = "com.github.ben-manes.versions" initscript { repositories { mavenLocal() gradlePluginPortal() } dependencies { classpath("com.github.ben-manes:gradle-versions-plugin:+") } } projectsEvaluated { allprojects { // 和項(xiàng)目配置沖突,如果項(xiàng)目中已經(jīng)配置了就忽略本配置 if (!plugins.hasPlugin(PLUGIN_ID)) { configureDependencyUpdates() logger.info("project '$name' apply plugin: $PLUGIN_ID") } } } val String.isNonStable get() = listOf("final", "rc", "m", "alpha", "beta", "ga").any { val regex = "^(?i).*[.-]${it}[.\\d-]*$".toRegex() regex.matches(this) } // 版本號(hào)以 v 開頭,比如:v1.1.1 val String.startsWithV get() = startsWith("v") fun Project.configureDependencyUpdates() { apply<VersionsPlugin>() tasks.withType<DependencyUpdatesTask> { group = GROUP_NAME rejectVersionIf { !currentVersion.isNonStable && candidate.version.isNonStable || currentVersion.startsWithV && !candidate.version.startsWithV } } }
配置 SDK
-
打開 IntelliJ IDEA 新建一個(gè)安卓項(xiàng)目
這時(shí)因?yàn)檫€沒有安裝 Android SDK 所以無(wú)法新建項(xiàng)目,會(huì)提示我們?nèi)グ惭b( 如下圖所示:
Install SDK
)。我們照著提示安裝就好了,安裝路徑會(huì)自動(dòng)識(shí)別為我們前面設(shè)置的環(huán)境變量ANDROID_SDK_ROOT
。新建安卓項(xiàng)目 - Android SDK 未安裝新建安卓項(xiàng)目 - Android SDK 安裝完成安裝完成就可以繼續(xù)新建項(xiàng)目了( 隨便建一個(gè) Basic Activity 的手機(jī)項(xiàng)目 )。
注意:
Android 31 依賴:( 參考 )
- com.android.tools.build:gradle:7.x
- Minimum supported Gradle version is 7.0.2.
- IntelliJ IDEA (or Android Studio) with version 2020.3.1 or newer.
當(dāng)然,也可以進(jìn)設(shè)置頁(yè)面自定義選擇 SDK 版本進(jìn)行安裝( 參考 ), API 19 + 可以兼容目前大部分的項(xiàng)目和手機(jī)。
Android SDK 設(shè)置新版本 IntelliJ IDEA 真的很方便,不像 N 年前用 Eclipse 開發(fā)時(shí)要自己去網(wǎng)上東找西找地下載各種 SDK 然后配置。
-
打開新建的項(xiàng)目
打開項(xiàng)目后會(huì)自動(dòng)識(shí)別為 Gradle 項(xiàng)目,開始自動(dòng)下載對(duì)應(yīng)的 Gradle wrapper 和依賴包。剛開始使用的話因?yàn)楸镜貨]緩存所以下載會(huì)比較久,用一段時(shí)間以后攢夠了緩存,之后再開任何項(xiàng)目就會(huì)比較快了。
一般來說不用像 Maven 一樣下載一個(gè)全局的 Gradle ,因?yàn)轫?xiàng)目外基本用不上,而項(xiàng)目?jī)?nèi)每個(gè)項(xiàng)目設(shè)置的 Gradle 版本基本上都不一樣,還是要下載多個(gè)版本的。
同步項(xiàng)目的時(shí)候可能會(huì)出現(xiàn)下面的錯(cuò)誤:
你的主機(jī)中的軟件中止了一個(gè)已建立的連接。 # 查看 daemon 日志關(guān)鍵內(nèi)容 .gradle/daemon/6.7.1/daemon-17316.out.log Ignoring unreachable local address on loopback interface /127.0.0.1 ... Adding remote address /192.168.137.1 ... Listening on [951c7aa5-4ce6-4311-8262-55d1396408a5 port:8653, addresses:[localhost/127.0.0.1]]. ... Daemon server started. ... Cannot accept connection from remote address /127.0.0.1.
看到
192.168.137.1
我就想起了熱點(diǎn),把熱點(diǎn)關(guān)閉果然就好了,殺 daemon 后再打開熱點(diǎn)就又不行了。總結(jié)下:- 有問題的 Gradle 版本為
6.4.1 ~ 6.8.3
,新建的項(xiàng)目版本為6.7.1
,在這個(gè)區(qū)間內(nèi)。 - 應(yīng)該是開啟熱點(diǎn)產(chǎn)生的虛擬網(wǎng)卡對(duì) daemon 綁定端口和通訊的邏輯產(chǎn)生了干擾,導(dǎo)致 daemon 啟動(dòng)后就關(guān)閉了。
- daemon 進(jìn)程正常啟動(dòng)后再開啟熱點(diǎn)就不會(huì)有問題了。
-
Easy Gradle 插件的
Kill Gradle
按鈕可以殺死 daemon 進(jìn)程。
- 有問題的 Gradle 版本為
安裝插件
-
查看設(shè)備當(dāng)前創(chuàng)建的 Activity 的堆棧狀態(tài),對(duì)應(yīng)下面的命令:
adb shell dumpsys activity activities
此插件即將下架,感興趣的可以看下 源碼 。
-
可以測(cè)試 URL Scheme 。
-
提供常用的 adb 命令菜單( 啟動(dòng)、關(guān)閉、調(diào)試等 ),快捷鍵
Ctrl + Alt + Shift + A
。 -
唯一有用的功能就是能修改手機(jī)的分辨率。
-
無(wú)需手動(dòng)敲命令,一鍵通過 WiFi 連接安卓手機(jī)。眾多同類插件中顏值最高,還集成了 scrcpy 。
使用 scrcpy 的時(shí)候可能會(huì)出現(xiàn)卡頓,我測(cè)試了兩個(gè)手機(jī)發(fā)現(xiàn) adb wifi 的帶寬最多只能跑到 5 Mbps ,慢得離譜( USB 差不多能跑 80 Mbps ),要想流暢點(diǎn)就要降低比特率和分辨率。
adb push D:/xxx /sdcard/
按照網(wǎng)上的 方法 通過熱點(diǎn)( 電腦開熱點(diǎn)或者手機(jī)開熱點(diǎn)都行 )直連的話,帶寬可以提升到 14 Mbps ,還是遠(yuǎn)遠(yuǎn)不夠,這個(gè)速度安裝微信這種 APK 光復(fù)制文件都要好幾分鐘。
-
自定義 Intent 調(diào)試。
-
一鍵生成 proguard-rules.pro 中的混淆配置,僅供參考。
-
在線查看 Android 源碼的插件。
-
支持手動(dòng)輸入 IP 和端口進(jìn)行連接,支持掃描局域網(wǎng)可用設(shè)備,設(shè)備列表會(huì)持久化而不丟失。
-
APK 反編譯為 Smali ( 可用 Jadx 打開 )。
-
Drawable 文件直接預(yù)覽在項(xiàng)目視圖的圖標(biāo)上,無(wú)需打開文件。
用是能用,不過有時(shí)能顯示出來有時(shí)又顯示不出來,應(yīng)該是性能上有問題。
-
反編譯 Dex 中的字節(jié)碼,不過年久失修用不了了。
-
提供一個(gè)按鈕強(qiáng)行終止 Gradle 進(jìn)程。
-
清理 Gradle 緩存的 Snapshot 依賴包。
-
擴(kuò)展 Gradle 工具窗口,管理本地的 Gradle 信息和緩存。
-
查看 Gradle 依賴樹。
由于依賴 Gradle Tooling API
5.6.2
,最高只能支持到 Gradle6.x
。 -
在項(xiàng)目中右鍵安裝 APK 而無(wú)需手動(dòng)敲命令。
-
集成 Jadx GUI ,一個(gè) Dex 到 Java 的反編譯器,可在項(xiàng)目文件( apk, dex, jar, class, smali, zip, aar, arsc )視圖中右鍵選擇 在 Jadx GUI 中反編譯 。
Jadx 是目前我用過最好用的、最傻瓜式的 APK 反編譯器 ,不過需要設(shè)置好內(nèi)存參數(shù)
-Xmx
( 參考 ),不然隨便多開幾個(gè)就能撐爆你的內(nèi)存。 -
Material Design Icon Generator
輔助導(dǎo)入 Material Design 圖標(biāo)到項(xiàng)目中,快捷鍵
Ctrl + Alt + D
。 -
直接給 scrcpy 做了一個(gè)配置界面,使用更方便。當(dāng)然,還是 QtScrcpy 的體驗(yàn)更好。
scrcpy 是一個(gè)手機(jī)投屏到電腦的工具,有了它就可以在電腦上無(wú)縫操作手機(jī),調(diào)試可以更加方便( 尤其是有多個(gè)開發(fā)設(shè)備 )。
-
Plugin Helps you to have full control of your project and device.
-
看截圖應(yīng)該是個(gè)不錯(cuò)的數(shù)據(jù)庫(kù)管理工具,不過太久沒更新了,安裝后使用沒反應(yīng)甚至?xí)?IDE 卡死。新版 IDE 可以考慮自帶的 Database Inspector 。
-
顯示安卓項(xiàng)目中所有的 Drawable 文件。
其他配置和功能
-
代碼風(fēng)格
Settings -> Editor -> Code Style
-
gradle.properties 中的
kotlin.code.style
配置項(xiàng)會(huì)決定基礎(chǔ)樣式。( 參考 )按照 ktlint 的教程一鍵配置,應(yīng)用到項(xiàng)目級(jí)別即可,免得惡心到其他項(xiàng)目。
另外,開啟樣式檢查可以幫助你快速找到項(xiàng)目中需要格式化的代碼。
Settings -> Editor -> Inspections
Kotlin -> Style issues -> File is not formatted according to project settings
enable
Apply only to modified files
參考:
-
Set from... -> Android
導(dǎo)入 Android 的 XML 代碼樣式。
啟用屬性排列很有用,比如 layout 屬性不再雜亂無(wú)章。( 參考 )
XML 屬性排列規(guī)則
-
-
安卓模擬器 內(nèi)嵌在 Tool Windows 中打開
Settings -> Tools -> Android Emulator
-
Launch in a tool window
-
-
Android 資源文件默認(rèn)打開界面模式為純代碼編輯
Settings -> Editor -> Android Layout Editor -> Default Editor Mode
-
Code
-
-
Code ( Analyze ) -> Analyze Stack Trace...
-
使用布局檢查器和布局驗(yàn)證工具調(diào)試布局 ( 參考 )
View -> Tool Windows -> Layout Inspector ( 僅安卓項(xiàng)目可見 )
要啟用實(shí)時(shí)刷新要安裝 Layout Inspector image server for xxx 。( 使用時(shí)應(yīng)該會(huì)自動(dòng)安裝 )
-
使用 Database Inspector 調(diào)試數(shù)據(jù)庫(kù) ( 參考 )
View -> Tool Windows -> [App Inspection] -> Database Inspector ( 僅安卓項(xiàng)目可見 )
-
使用后臺(tái)任務(wù)檢查器調(diào)試 WorkManager 工作器 (
Android Studio Arctic Fox+
)View -> Tool Windows -> App Inspection -> Background Task Inspector ( 僅安卓項(xiàng)目可見 )
-
View -> Tool Windows -> Device File Explorer ( 僅安卓項(xiàng)目可見 )
修改默認(rèn)的文件下載目錄:
Settings -> Tools -> Android Device File Explorer -> Download location
-
雙擊打開 APK 文件即可。
-
利用 uiautomatorviewer 來檢查當(dāng)前屏幕顯示的布局層次結(jié)構(gòu)
uiautomatorviewer
工具位于<android-sdk>/tools/bin
目錄中。 -
AGP 配置 可視化
Android Studio 的 Project Structure 對(duì)應(yīng)為 IntelliJ IDEA 的
Settings -> Build, Execution, Deployment -> Android Project Structure
不成熟,動(dòng)態(tài)生成的配置基本識(shí)別不出來。
-
查看 Keymap 設(shè)置我們可以發(fā)現(xiàn)里面有很多的功能,不可能給它們?nèi)吭O(shè)置快捷鍵。這時(shí)候就可以通過 quick list 把一些我們常用的功能整合在一起,然后設(shè)置一個(gè)快捷鍵來快速打開這個(gè)菜單面板,十分方便。
-
將外部程序作為一個(gè)功能簡(jiǎn)單集成到 IDE 中( 命令行調(diào)用 ),可添加到 Quick Lists 。
Tools -> External Tools -> xxx
常見錯(cuò)誤
-
找不到 SDK
SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.
Android Studio 在同步 Gradle 前會(huì)自動(dòng)創(chuàng)建 local.properties 文件,而 IntelliJ IDEA 不會(huì)。
為了避免每次打開新項(xiàng)目要手動(dòng)創(chuàng)建,可以添加一個(gè)環(huán)境變量
ANDROID_HOME
( 參考 )。 -
使用老舊 Gradle 的項(xiàng)目( 比如 )構(gòu)建失敗
Executing tasks: [:app:assembleDebug] in project ...
Gradle build failed with 1 error(s) in 24 ms
找不到任何更多的錯(cuò)誤信息,而且手動(dòng)跑命令是完全沒問題的。
# gradlew :app:assembleDebug BUILD SUCCESSFUL in 0s 25 actionable tasks: 1 executed, 24 up-to-date
測(cè)試了 Android Studio ( Arctic Fox | 2020.3.1 ) 和 IntelliJ IDEA 2020.3 都沒問題,但 IntelliJ IDEA 2021.x 全都不行。
臨時(shí)解決方案 :構(gòu)建步驟使用 Gradle 命令代替
Gradle-aware Make
。( 參考 )Edit Configurations -> Android App -> app -> Before launch
- Gradle-aware Make + Run Gradle task :app:assembleDebug
如果繼續(xù)報(bào)錯(cuò),可以考慮把安裝步驟也替換了。( 參考 )
ApkProvisionException: No outputs for the main artifact of variant: debug
學(xué)習(xí)資料
- 官方文檔 - Android 開發(fā)者指南
- 官方文檔 - Android Studio
- 官方文檔 - 使用 Kotlin 開發(fā) Android 應(yīng)用
- Kotlin 基礎(chǔ)語(yǔ)法
- Gradle 用戶手冊(cè)
新手入門強(qiáng)烈建議去看一遍官方文檔,可以少走很多彎路。