在WSL上搭建Andriod开发环境并完成HelloWorld示例

这是在WSL2上无GUI实现的Android开发与Hello World demo的完整指南。对于零基础新手,在没有Android Studio (GUI)的情况下开发Android应用,核心逻辑是:用纯文本编辑器写代码 -> 用Gradle命令行编译出APK-> 用ADB命令行安装到手机

本文主要根据基于Aider的gemini-3.1-pro-preview的指引完成。已经根据指引顺利完成Demo的调试与显示。换言之,主要指南来自LLM AI,作者按步完成了相关操作,保证了教程的真实性,同时对AI的输出与结果进行了一定的筛选与重组,保证步骤的简洁高效。步骤中遇到的坑我会尽可能在整合的过程中指出来。

第一部分:WSL2 环境搭建 (只需做一次)

这部分没有什么大坑,我在跟随的时候没有报错,也没有在后续因为这个位置的问题产生过报错。

1. 安装 Java 运行环境 (JDK)

Android编译依赖Java。在WSL2(Ubuntu)终端中运行:

sudo apt update
sudo apt install openjdk-17-jdk wget unzip git -y

验证安装:java -version(应显示openjdk 17)

java -version

这是验证的输出

# openjdk version "17.0.19" 2026-04-21
# OpenJDK Runtime Environment (build 17.0.19+10-1-22.04.2-Ubuntu)
# OpenJDK 64-Bit Server VM (build 17.0.19+10-1-22.04.2-Ubuntu, mixed mode, sharing)

2. 下载 Android 命令行工具

我们需要Google官方提供的commandlinetools。shell命令如下执行。

# 创建存放 SDK 的目录
mkdir -p ~/android-sdk/cmdline-tools
cd ~/android-sdk/cmdline-tools

# 下载命令行工具 (链接可能会随时间更新,这是目前的最新版)
wget https://dl.google.com/android/repository/commandlinetools-linux-10406996_latest.zip

# 解压
unzip commandlinetools-linux-*_latest.zip

# 【关键步骤】必须将解压出的文件夹重命名为 latest
mv cmdline-tools latest
rm commandlinetools-linux-*_latest.zip

3. 配置环境变量

告诉系统你的SDK在哪里。编辑你的bash配置文件。这里是可以的,但我用的是ohmyzsh,所以我是直接在~/.zshrc的末尾追加的

nano ~/.zshrc

在文件最末尾添加以下三行:

export ANDROID_HOME=$HOME/android-sdk
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools

保存并退出(Ctrl+O, Enter, Ctrl+X),然后刷新配置:

source ~/.zshrc

4. 安装 Android SDK 组件

使用sdkmanager下载编译所需的工具,只有第3步的环境变量刷新了,这里才能使用sdkmanager:

# 自动同意所有霸王条款许可
yes | sdkmanager --licenses

# 安装平台工具(adb)、构建工具和 API 34 (Android 14)
sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0"

第二部分:创建 Hello World 项目

在没有IDE的情况下,我们需要手动创建Android项目的目录结构。请在WSL2 终端中依次执行以下命令,这会自动为你生成一个完整的极简项目。

需要说明的是,这里是坑最多的,这里本身的报错并不多,但由于这里的配置的问题,后面的编译运行会报错很多。当然我这里已经给出了准备的配置等等内容了,重点有坑的地方我会指出来。

1. 创建项目目录

mkdir -p ~/MyHelloWorld/app/src/main/java/com/example/helloworld
mkdir -p ~/MyHelloWorld/app/src/main/res/layout
mkdir -p ~/MyHelloWorld/app/src/main/res/values
cd ~/MyHelloWorld

2. 写入配置文件

  • 生成settings.gradle(告诉Gradle包含app模块):
cat <<EOF > settings.gradle
include ':app'
rootProject.name = "MyHelloWorld"
EOF
  • 生成项目级build.gradle:
cat <<EOF > build.gradle
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.1.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}
EOF

这里有第二个坑,是的是第二个坑,第一个坑在后面的位置。顺序没有错,我是按发现的顺序写的。

这里有一个旧版的build.gradle 我没有给出来,因为它导致后面的编译报错了,旧版的build.gradle脚本中,只定义了“构建脚本本身”去哪里下载插件(buildscript里的 repositories),却漏掉了告诉Gradle“App代码”去哪里下载依赖库。

解决办法:

我们需要修改项目根目录下的build.gradle文件,把allprojects仓库配置加上,也就是上面的脚本内容。

  • 生成 App 级 app/build.gradle:
cat <<EOF > app/build.gradle
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    namespace 'com.example.helloworld'
    compileSdk 34

    defaultConfig {
        applicationId "com.example.helloworld"
        minSdk 24
        targetSdk 34
        versionCode 1
        versionName "1.0"
    }

    // 新增:统一 Java 编译版本为 17
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }

    // 新增:统一 Kotlin 编译版本为 17
    kotlinOptions {
        jvmTarget = '17'
    }
}
EOF

这里有第三个坑。最原始的版本我没有提供,它仍然会报错,因为Android Gradle插件(AGP)默认把Java 代码编译为Java 8 (1.8)版本,但是我们安装的系统环境是Java 17,Kotlin编译器自动使用了Java 17。两者版本不一致导致了冲突。

解决办法: 我们需要在app/build.gradle中明确告诉Android构建系统:“请把Java和Kotlin都统一使用Java 17来编译”。这就是上面的配置文件修改正确的地方,也就是显式指定了java的版本,保证了前后一致性。

3. 写入 Android 核心代码

  • 生成AndroidManifest.xml(应用的清单文件):
cat <<EOF > app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:label="Hello WSL">
        <activity android:name=".MainActivity" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
EOF
  • 生成MainActivity.kt(主界面逻辑):
cat <<EOF > app/src/main/java/com/example/helloworld/MainActivity.kt
package com.example.helloworld

import android.app.Activity
import android.os.Bundle
import android.widget.TextView

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 用代码直接创建一个文本视图,不使用 xml 布局文件以保持极简
        val textView = TextView(this)
        textView.text = "Hello World from WSL2!"
        textView.textSize = 24f

        setContentView(textView)
    }
}
EOF

4. 初始化 Gradle Wrapper

请将这一步整个看完再跟进,否则就掉坑里了。

在项目根目录(~/MyHelloWorld) 执行:

gradle wrapper --gradle-version 8.2

(如果提示找不到gradle命令,可以先sudo apt install gradle安装系统级gradle来生成wrapper)

zsh: command not found: gradle

这里是第一个坑,上面的bash命令实际上会报错,因为目前系统上根本就没有gradle。是的,我们之前的那么多准备工作都没有安装gradle。

因为我们刚才通过sdkmanager安装的,是Android SDK(安卓软件开发工具包),里面包含的是安卓专属的工具(比如adb调试工具、打包工具等)。

而Gradle是一个通用的构建工具(类似于C语言的make),它并不包含在Android SDK中。

在现代Android开发中,标准的做法是使用Gradle Wrapper(gradlew)。它是一个脚本,能让你的项目自带一个特定版本的 Gradle,这样别人拿到你的代码就不需要手动去配置Gradle环境了。

但是,因为我们是纯手工从零创建的空文件夹,里面还没有这个gradlew脚本,所以我们需要先用系统级的gradle命令来“生成”它。

所以在上面的第4步之前我们得先做一个准备步骤:临时安装一个系统级的Gradle。

但是这时有第二个坑,那就是不要用ubuntu的apt命令安装gradle,因为这样安装的gradle的版本才4.4.1,版本太低,与我们的项目不兼容,运行gradle wrapper --gradle-version 8.2时会报错。

这是因为我们在第一步安装了较新的Java 17,但是Ubuntu系统自带的apt仓库里的gradle版本太老了(通常是4.x或 6.x)。老版本的Gradle不认识Java 17的新安全机制,所以直接崩溃了。

解决办法:手动下载新版Gradle来生成Wrapper

既然系统的Gradle太老,我们就直接从官网下载一个新版的Gradle临时用一下。请在终端依次执行以下命令。我们需要直接下载grade来安装。

在终端运行以下命令安装:

cd /tmp
wget https://services.gradle.org/distributions/gradle-8.2-bin.zip
unzip gradle-8.2-bin.zip

cd ~/MyHelloWorld
/tmp/gradle-8.2/bin/gradle wrapper

./gradlew --version

命令行的一部分输出是这样的

(base) ➜  MyHelloWorld /tmp/gradle-8.2/bin/gradle wrapper

Welcome to Gradle 8.2!

Here are the highlights of this release:
 - Kotlin DSL: new reference documentation, assignment syntax by default
 - Kotlin DSL is now the default with Gradle init
 - Improved suggestions to resolve errors in console output

For more details see https://docs.gradle.org/8.2/release-notes.html

Starting a Gradle Daemon (subsequent builds will be faster)

BUILD SUCCESSFUL in 1m 9s
1 actionable task: 1 executed
(base) ➜  MyHelloWorld ./gradlew --version
Downloading https://services.gradle.org/distributions/gradle-8.2-bin.zip
............10%............20%............30%.............40%............50%............60%............70%.............80%............90%............100%

------------------------------------------------------------
Gradle 8.2
------------------------------------------------------------

Build time:   2023-06-30 18:02:30 UTC
Revision:     5f4a070a62a31a17438ac998c2b849f4f6892877

Kotlin:       1.8.20
Groovy:       3.0.17
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          17.0.19 (Ubuntu 17.0.19+10-1-22.04.2-Ubuntu)
OS:           Linux 6.18.33.2-microsoft-standard-WSL2 amd64

上面的工作做完了以后,下面的命令其实就没有必要运行了,比如你可以试下,也没有影响,也就是说,这个命令的替换版本已经在上面的过程中,用/tmp/gradle-8.2/bin/gradle wrapper运行过了,不需要再运行了,如果你运行了,因为没有安装grade,你反而会报错,但是我们实际上通过/tmp/gradle-8.2/bin/gradle wrapper已经完成了相同的任务。

# 不需要再运行这个命令了!!!
gradle wrapper --gradle-version 8.2

这次就会成功了。你会发现项目目录下多出了gradlew和gradlew.bat文件。

这一步的最后,我们说:

以后只用./gradlew。一旦生成了这个Wrapper,你以后在这个项目里就再也不需要用gradle命令了。

第三部分:编译与运行

1. 编译 APK

接下来的编译步骤,请严格使用带有./的命令:

在~/MyHelloWorld目录下执行:

./gradlew assembleDebug

(./gradlew会自动去下载8.2版本的完整Gradle并执行编译,这正是无GUI开发的精髓所在)。

如果你的第二部分的所有文件写入都是对的,这里是可以编译成功,生成apk文件的,我亲测在修改为上面的配置后,我的环境中,apk生成成功了。这里一小部分命令行输出。

If you are already using the latest version of the Android Gradle plugin,
you may need to wait until a newer version with support for compileSdk = 34 is available.

To suppress this warning, add/update
    android.suppressUnsupportedCompileSdk=34
to this project's gradle.properties.

BUILD SUCCESSFUL in 7s
32 actionable tasks: 9 executed, 23 up-to-date

第一次运行会非常慢,因为Gradle需要下载大量的依赖包。看到BUILD SUCCESSFUL就说明编译成功了!编译好的APK位于:app/build/outputs/apk/debug/app-debug.apk

2. 连接手机 (无线调试)

由于WSL2连USB比较麻烦,强烈推荐无线调试(要求手机和电脑连同一个WiFi):

  • 在你的手机/平板上,进入“设置” -> “关于手机” -> 连续点击“版本号”7次开启开发者模式。
  • 进入“开发者选项”,开启“无线调试”。
  • 点击“无线调试”进入详情页,选择“使用配对码配对设备”。你会看到一个IP地址、端口号和一个6位数的配对码。
  • 在WSL2终端输入:
adb pair <手机显示的IP>:<配对端口>

输入 6 位数配对码。

  • 配对成功后,查看手机无线调试页面上的“IP地址和端口”(注意端口号和刚才配对的端口不一样),在 WSL2 中输入:
adb connect <手机显示的IP>:<连接端口>

以上我没有按照上面的教程执行,我是在samsung的P200平板上调试安装的,我有直接的WiFi Debug权限,因为我此前有root过。所以我知道我的手机的ip以及默认端口号是5555

我可以直接在shell中运行:

adb connect <手机IP>:<5555>

第一次连接会报错,同时平板上会弹窗提示是否同意配对连接,点确定就可以了。

然后重新执行上面的命令,就会提示连接成功了。命令行显示如下:

(base) ➜  MyHelloWorld adb connect 192.168.0.xxx:5555
* daemon not running; starting now at tcp:5037
* daemon started successfully
failed to authenticate to 192.168.0.xxx:5555
(base) ➜  MyHelloWorld adb connect 192.168.0.xxx:5555
already connected to 192.168.0.xxx:5555

3. 安装并运行

连接成功后,将刚才编译的APK安装到手机上:

adb install app/build/outputs/apk/debug/app-debug.apk

安装成功后,你的手机桌面上就会出现一个名为"Hello WSL"的应用,打开它,你就能看到"Hello World from WSL2!“了!

内容声明与版权协议

  • 版权协议:本文采用 CC BY-NC-SA 4.0(署名-非商业性使用-相同方式共享) 协议进行许可。转载、演绎请务必保留作者署名及原文链接,且不得用于商业目的。
  • AI 辅助说明:本博客部分内容(如排版设计、个别局部、特定对话片段等)可能由 AI(LLM大语言模型)辅助生成。作者在此明确声明:本人对文章的核心框架、思想立论与最终呈现拥有绝对主导权与最终解释权。
  • 观点免责:文中明示的由 AI 生成的特定文本、对话输出,仅作为理性探讨以及观点展示,不代表本人真实立场、价值观或事实背书。对于因 AI 幻觉造成的客观事实偏差,请读者审慎甄别。
  • 认知时效性:文章仅代表作者在撰写当下的认知状态与情绪切片。随着个人心智迭代与客观事物发展,作者观点可能发生演变。欢迎基于理性的交流与批评。