บทแนะนำ Bazel: สร้างแอป Android

รายงานปัญหา ดูแหล่งที่มา Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

หมายเหตุ: มีข้อจำกัดที่ทราบในการใช้ Bazel เพื่อสร้างแอป Android ไปที่หน้าปัญหาเกี่ยวกับกฎ_android เพื่อดูรายการปัญหาที่ทราบ แม้ว่าทีม Bazel และผู้มีส่วนร่วมในซอฟต์แวร์โอเพนซอร์ส (OSS) จะทำงานอย่างแข็งขันเพื่อแก้ไขปัญหาที่ทราบ แต่ผู้ใช้ควรทราบ ว่า Android Studio ไม่รองรับโปรเจ็กต์ Bazel อย่างเป็นทางการ

บทแนะนำนี้ครอบคลุมวิธีสร้างแอป Android อย่างง่ายโดยใช้ Bazel

Bazel รองรับการสร้างแอป Android โดยใช้ กฎ Android

บทแนะนำนี้มีไว้สำหรับผู้ใช้ Windows, macOS และ Linux และไม่จำเป็นต้องมีประสบการณ์ในการใช้ Bazel หรือการพัฒนาแอป Android คุณไม่จำเป็นต้อง เขียนโค้ด Android ในบทแนะนำนี้

สิ่งที่คุณจะได้เรียนรู้

ในบทแนะนำนี้ คุณจะได้เรียนรู้วิธีทำสิ่งต่อไปนี้

  • ตั้งค่าสภาพแวดล้อมโดยการติดตั้ง Bazel และ Android Studio รวมถึง ดาวน์โหลดโปรเจ็กต์ตัวอย่าง
  • ตั้งค่าพื้นที่ทำงาน Bazel ที่มีซอร์สโค้ด สำหรับแอปและไฟล์ MODULE.bazel ที่ระบุระดับบนสุดของ ไดเรกทอรีพื้นที่ทำงาน
  • อัปเดตไฟล์ MODULE.bazel ให้มีข้อมูลอ้างอิงถึงทรัพยากร Dependency ภายนอกที่จำเป็น เช่น Android SDK
  • สร้างไฟล์ BUILD
  • สร้างแอปด้วย Bazel
  • ติดตั้งใช้งานและเรียกใช้แอปในโปรแกรมจำลอง Android หรืออุปกรณ์จริง

ก่อนเริ่มต้น

ติดตั้ง Bazel

ก่อนเริ่มบทแนะนำนี้ ให้ติดตั้งซอฟต์แวร์ต่อไปนี้

  • Bazel ทำตามวิธีการติดตั้งเพื่อติดตั้ง
  • Android Studio หากต้องการติดตั้ง ให้ทำตามขั้นตอนเพื่อดาวน์โหลด Android Studio เรียกใช้ตัวช่วยสร้างการตั้งค่าเพื่อดาวน์โหลด SDK และกำหนดค่าสภาพแวดล้อม
  • (ไม่บังคับ) Git ใช้ git เพื่อดาวน์โหลดโปรเจ็กต์แอป Android

รับโปรเจ็กต์ตัวอย่าง

สำหรับโปรเจ็กต์ตัวอย่าง ให้ใช้โปรเจ็กต์แอป Android แบบบทแนะนำในที่เก็บตัวอย่างของ Bazel

แอปนี้มีปุ่มเดียวที่พิมพ์คำทักทายเมื่อคลิก

คำทักทายด้วยปุ่ม

รูปที่ 1 คำทักทายของปุ่มแอป Android

โคลนที่เก็บด้วย git (หรือดาวน์โหลดไฟล์ ZIP โดยตรง)

git clone https://github.com/bazelbuild/examples

โปรเจ็กต์ตัวอย่างสำหรับบทแนะนำนี้อยู่ใน examples/android/tutorial สำหรับ ส่วนที่เหลือของบทแนะนำ คุณจะเรียกใช้คำสั่งในไดเรกทอรีนี้

ตรวจสอบไฟล์ต้นฉบับ

ดูไฟล์ต้นฉบับของแอป

.
├── README.md
└── src
    └── main
        ├── AndroidManifest.xml
        └── java
            └── com
                └── example
                    └── bazel
                        ├── AndroidManifest.xml
                        ├── Greeter.java
                        ├── MainActivity.java
                        └── res
                            ├── layout
                            │   └── activity_main.xml
                            └── values
                                ├── colors.xml
                                └── strings.xml

ไฟล์และไดเรกทอรีที่สำคัญมีดังนี้

ชื่อ ตำแหน่ง
ไฟล์ Manifest ของ Android src/main/AndroidManifest.xml และ src/main/java/com/example/bazel/AndroidManifest.xml
ไฟล์ต้นฉบับของ Android src/main/java/com/example/bazel/MainActivity.java และ Greeter.java
ไดเรกทอรีไฟล์ทรัพยากร src/main/java/com/example/bazel/res/

สร้างด้วย Bazel

ตั้งค่าพื้นที่ทำงาน

พื้นที่ทำงานคือไดเรกทอรีที่มี ไฟล์ต้นฉบับสำหรับโปรเจ็กต์ซอฟต์แวร์อย่างน้อย 1 รายการ และมีไฟล์ MODULE.bazel อยู่ที่ รูท

MODULE.bazel อาจว่างเปล่าหรืออาจมีการอ้างอิงถึงการอ้างอิงภายนอกที่จำเป็นต่อการสร้างโปรเจ็กต์

ก่อนอื่น ให้เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างไฟล์ MODULE.bazel ที่ว่างเปล่า

ระบบปฏิบัติการ คำสั่ง
Linux, macOS touch MODULE.bazel
Windows (Command Prompt) type nul > MODULE.bazel
Windows (PowerShell) New-Item MODULE.bazel -ItemType file

การเรียกใช้ Bazel

ตอนนี้คุณสามารถตรวจสอบว่า Bazel ทำงานอย่างถูกต้องหรือไม่ด้วยคำสั่งต่อไปนี้

bazel info workspace

หาก Bazel พิมพ์เส้นทางของไดเรกทอรีปัจจุบัน แสดงว่าคุณพร้อมใช้งานแล้ว หากไม่มีไฟล์ MODULE.bazel คุณอาจเห็นข้อความแสดงข้อผิดพลาดดังนี้

ERROR: The 'info' command is only supported from within a workspace.

ผสานรวมกับ Android SDK

Bazel ต้องเรียกใช้ Build Tools ของ Android SDK เพื่อสร้างแอป ซึ่งหมายความว่าคุณต้องเพิ่มข้อมูลบางอย่างลงในไฟล์ MODULE.bazel เพื่อให้ Bazel รู้ตำแหน่งของเครื่องมือ

เพิ่มบรรทัดต่อไปนี้ลงในไฟล์ MODULE.bazel

bazel_dep(name = "rules_android", version = "0.6.6")

remote_android_extensions = use_extension(
    "@rules_android//bzlmod_extensions:android_extensions.bzl",
    "remote_android_tools_extensions")
use_repo(remote_android_extensions, "android_tools")

android_sdk_repository_extension = use_extension("@rules_android//rules/android_sdk_repository:rule.bzl", "android_sdk_repository_extension")
use_repo(android_sdk_repository_extension, "androidsdk")

ซึ่งจะใช้ Android SDK ที่เส้นทางซึ่งอ้างอิงโดยANDROID_HOME ตัวแปรสภาพแวดล้อม และตรวจหาระดับ API สูงสุดและ เครื่องมือสร้างเวอร์ชันล่าสุดที่ติดตั้งภายในตำแหน่งนั้นโดยอัตโนมัติ

คุณตั้งค่าตัวแปร ANDROID_HOME เป็นตำแหน่งของ Android SDK ได้ ค้นหา เส้นทางไปยัง SDK ที่ติดตั้งโดยใช้ SDK Manager ของ Android Studio หากติดตั้ง SDK ไว้ในตำแหน่งเริ่มต้น คุณจะใช้คำสั่งต่อไปนี้เพื่อตั้งค่าตัวแปร ANDROID_HOME ได้

ระบบปฏิบัติการ คำสั่ง
Linux export ANDROID_HOME=$HOME/Android/Sdk/
macOS export ANDROID_HOME=$HOME/Library/Android/sdk
Windows (Command Prompt) set ANDROID_HOME=%LOCALAPPDATA%\Android\Sdk
Windows (PowerShell) $env:ANDROID_HOME="$env:LOCALAPPDATA\Android\Sdk"

คำสั่งข้างต้นจะตั้งค่าตัวแปรสำหรับเซสชันเชลล์ปัจจุบันเท่านั้น หากต้องการให้ การเปลี่ยนแปลงมีผลถาวร ให้เรียกใช้คำสั่งต่อไปนี้

ระบบปฏิบัติการ คำสั่ง
Linux echo "export ANDROID_HOME=$HOME/Android/Sdk/" >> ~/.bashrc
macOS echo "export ANDROID_HOME=$HOME/Library/Android/Sdk/" >> ~/.bashrc
Windows (Command Prompt) setx ANDROID_HOME "%LOCALAPPDATA%\Android\Sdk"
Windows (PowerShell) [System.Environment]::SetEnvironmentVariable('ANDROID_HOME', "$env:LOCALAPPDATA\Android\Sdk", [System.EnvironmentVariableTarget]::User)

ไม่บังคับ: หากต้องการคอมไพล์โค้ดเนทีฟลงในแอป Android คุณ จะต้องดาวน์โหลด Android NDK ด้วย และใช้ rules_android_ndk โดยเพิ่มบรรทัดต่อไปนี้ลงในไฟล์ MODULE.bazel

bazel_dep(name = "rules_android_ndk", version = "0.1.3")

ดูข้อมูลเพิ่มเติมได้ที่การใช้ Android Native Development Kit กับ Bazel

คุณไม่จำเป็นต้องตั้งค่าระดับ API ให้มีค่าเดียวกันสำหรับ SDK และ NDK หน้านี้ มีแผนที่จากรุ่น Android ไปยังระดับ API ที่ NDK รองรับ

สร้างไฟล์ BUILD

BUILD ไฟล์จะอธิบายความสัมพันธ์ ระหว่างชุดเอาต์พุตการสร้าง เช่น ทรัพยากร Android ที่คอมไพล์จาก aapt หรือ ไฟล์คลาสจาก javac กับทรัพยากรที่ขึ้นต่อกัน การอ้างอิงเหล่านี้อาจเป็น ไฟล์ต้นฉบับ (Java, C++) ในพื้นที่ทำงานหรือเอาต์พุตการสร้างอื่นๆ ไฟล์ BUILD เขียนด้วยภาษาที่เรียกว่า Starlark

ไฟล์ BUILD เป็นส่วนหนึ่งของแนวคิดใน Bazel ที่เรียกว่าลำดับชั้นของแพ็กเกจ ลำดับชั้นของแพ็กเกจคือโครงสร้างเชิงตรรกะที่ซ้อนทับโครงสร้างไดเรกทอรีในพื้นที่ทำงาน แพ็กเกจแต่ละรายการคือไดเรกทอรี (และไดเรกทอรีย่อย) ที่มีชุดไฟล์ต้นฉบับที่เกี่ยวข้อง และไฟล์ BUILD แพ็กเกจยังรวมถึงไดเรกทอรีย่อยทั้งหมดด้วย ยกเว้นไดเรกทอรีย่อยที่มีไฟล์ BUILD ของตัวเอง ชื่อแพ็กเกจคือเส้นทางไปยังไฟล์ BUILD สัมพัทธ์กับไฟล์ MODULE.bazel

โปรดทราบว่าลำดับชั้นของแพ็กเกจของ Bazel นั้นแตกต่างจากลำดับชั้นของแพ็กเกจ Java ในไดเรกทอรีแอป Android ที่มีไฟล์ BUILD อยู่ แม้ว่าไดเรกทอรีอาจจัดระเบียบเหมือนกันก็ตาม

สำหรับแอป Android อย่างง่ายในบทแนะนำนี้ ไฟล์ต้นฉบับใน src/main/ ประกอบด้วยแพ็กเกจ Bazel เดียว โปรเจ็กต์ที่ซับซ้อนมากขึ้นอาจมีแพ็กเกจที่ซ้อนกันหลายรายการ

เพิ่มกฎ android_library

BUILD มีการประกาศหลายประเภทสำหรับ Bazel ประเภทที่สำคัญที่สุดคือกฎการสร้าง ซึ่งจะบอก Bazel วิธีสร้างเอาต์พุตซอฟต์แวร์ขั้นกลางหรือขั้นสุดท้ายจากชุดไฟล์แหล่งที่มาหรือการอ้างอิงอื่นๆ Bazel มีกฎการสร้าง 2 ข้อ ได้แก่ android_library และ android_binary ซึ่งคุณใช้เพื่อ สร้างแอป Android ได้

สำหรับบทแนะนำนี้ คุณจะต้องใช้กฎ android_library ก่อนเพื่อบอกให้ Bazel สร้างไลบรารี Android โมดูล จากซอร์สโค้ดของแอปและไฟล์ทรัพยากร จากนั้นคุณจะใช้ android_binaryกฎเพื่อบอก Bazel วิธีสร้างแพ็กเกจแอปพลิเคชัน Android

สร้างไฟล์ BUILD ใหม่ในไดเรกทอรี src/main/java/com/example/bazel และประกาศเป้าหมาย android_library ใหม่

src/main/java/com/example/bazel/BUILD:

load("@rules_android//rules:rules.bzl", "android_library")

package(
    default_visibility = ["//src:__subpackages__"],
)

android_library(
    name = "greeter_activity",
    srcs = [
        "Greeter.java",
        "MainActivity.java",
    ],
    manifest = "AndroidManifest.xml",
    resource_files = glob(["res/**"]),
)

android_library กฎการสร้างมีชุดแอตทริบิวต์ที่ระบุข้อมูลที่ Bazel ต้องใช้ในการสร้างโมดูลไลบรารีจากไฟล์ต้นฉบับ นอกจากนี้ โปรดทราบว่าชื่อของกฎคือ greeter_activity คุณจะอ้างอิง กฎโดยใช้ชื่อนี้เป็นทรัพยากร Dependency ในandroid_binaryกฎ

เพิ่มกฎ android_binary

กฎ android_binary จะสร้าง แพ็กเกจแอปพลิเคชัน Android (ไฟล์ .apk) สำหรับแอป

สร้างไฟล์ BUILD ใหม่ในไดเรกทอรี src/main/ และประกาศเป้าหมาย android_binary ใหม่

src/main/BUILD:

load("@rules_android//rules:rules.bzl", "android_binary")

android_binary(
    name = "app",
    manifest = "//src/main/java/com/example/bazel:AndroidManifest.xml",
    deps = ["//src/main/java/com/example/bazel:greeter_activity"],
)

ในที่นี้ แอตทริบิวต์ deps จะอ้างอิงเอาต์พุตของกฎ greeter_activity ที่คุณเพิ่มลงในไฟล์ BUILD ด้านบน ซึ่งหมายความว่าเมื่อ Bazel สร้างเอาต์พุตของกฎนี้ จะตรวจสอบก่อนว่าเอาต์พุตของgreeter_activityกฎไลบรารีได้รับการสร้างและเป็นเวอร์ชันล่าสุดหรือไม่ หากไม่มี Bazel จะสร้างไฟล์ดังกล่าว แล้วใช้เอาต์พุตนั้นเพื่อสร้างไฟล์แพ็กเกจแอปพลิเคชัน

ตอนนี้ให้บันทึกและปิดไฟล์

สร้างแอป

ลองสร้างแอปเลย เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างเป้าหมาย android_binary

bazel build //src/main:app

คำสั่งย่อย build จะสั่งให้ Bazel สร้าง เป้าหมายที่ตามมา เป้าหมายจะระบุเป็นชื่อของกฎการสร้างภายในไฟล์ BUILD พร้อมกับเส้นทางแพ็กเกจที่สัมพันธ์กับไดเรกทอรีพื้นที่ทำงาน สำหรับตัวอย่างนี้ เป้าหมายคือ app และเส้นทางแพ็กเกจคือ //src/main/

โปรดทราบว่าบางครั้งคุณอาจละเว้นเส้นทางแพ็กเกจหรือชื่อเป้าหมายได้ ทั้งนี้ขึ้นอยู่กับ ไดเรกทอรีการทำงานปัจจุบันในบรรทัดคำสั่งและชื่อของเป้าหมาย ดูรายละเอียดเพิ่มเติมเกี่ยวกับป้ายกำกับและเส้นทางเป้าหมายได้ที่ป้ายกำกับ

Bazel จะเริ่มสร้างแอปตัวอย่าง ในระหว่างกระบวนการสร้าง เอาต์พุตจะปรากฏคล้ายกับเอาต์พุตต่อไปนี้

INFO: Analysed target //src/main:app (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //src/main:app up-to-date:
  bazel-bin/src/main/app_deploy.jar
  bazel-bin/src/main/app_unsigned.apk
  bazel-bin/src/main/app.apk

ค้นหาเอาต์พุตบิลด์

Bazel จะวางเอาต์พุตของการดำเนินการบิลด์ทั้งระดับกลางและขั้นสุดท้ายไว้ในชุดไดเรกทอรีเอาต์พุตต่อผู้ใช้และต่อพื้นที่ทำงาน ไดเรกทอรีเหล่านี้เป็นลิงก์สัญลักษณ์ จากตำแหน่งต่อไปนี้ที่ระดับบนสุดของไดเรกทอรีโปรเจ็กต์ ซึ่งเป็นตำแหน่งที่ไฟล์ MODULE.bazel อยู่

  • bazel-bin จัดเก็บไฟล์ไบนารีที่เรียกใช้งานได้และเอาต์พุตการบิลด์อื่นๆ ที่เรียกใช้งานได้
  • bazel-genfiles จัดเก็บไฟล์ต้นฉบับระดับกลางที่สร้างขึ้นโดยกฎ Bazel
  • bazel-out จัดเก็บเอาต์พุตบิลด์ประเภทอื่นๆ

Bazel จะจัดเก็บไฟล์ Android .apk ที่สร้างขึ้นโดยใช้กฎ android_binary ในไดเรกทอรี bazel-bin/src/main โดยชื่อไดเรกทอรีย่อย src/main จะ ได้มาจากชื่อของแพ็กเกจ Bazel

ที่พรอมต์คำสั่ง ให้แสดงเนื้อหาของไดเรกทอรีนี้และค้นหาไฟล์ app.apk

ระบบปฏิบัติการ คำสั่ง
Linux, macOS ls bazel-bin/src/main
Windows (Command Prompt) dir bazel-bin\src\main
Windows (PowerShell) ls bazel-bin\src\main

เรียกใช้แอป

ตอนนี้คุณสามารถทำให้แอปใช้งานได้ในอุปกรณ์ Android หรือโปรแกรมจำลองที่เชื่อมต่อจากบรรทัดคำสั่งโดยใช้ bazel mobile-install คำสั่งนี้ใช้ Android Debug Bridge (adb) เพื่อสื่อสารกับอุปกรณ์ คุณต้องตั้งค่าอุปกรณ์ให้ใช้ adb ตามวิธีการใน Android Debug Bridge ก่อนการติดตั้งใช้งาน นอกจากนี้ คุณยังเลือกติดตั้งแอปในโปรแกรมจำลอง Android ที่รวมอยู่ใน Android Studio ได้ด้วย ตรวจสอบว่าโปรแกรมจำลองทำงานอยู่ก่อนที่จะเรียกใช้ คำสั่งด้านล่าง

ป้อนข้อมูลต่อไปนี้

bazel mobile-install //src/main:app \
  --mode=skylark \
  --mobile_install_aspect=@rules_android//mobile_install:mi.bzl \
  --mobile_install_supported_rules=android_binary \
  --java_runtime_version=17 \
  --java_language_version=17 \
  --tool_java_runtime_version=17 \
  --tool_java_language_version=17

โปรดทราบว่าคุณสามารถเพิ่มแฟล็กพิเศษที่จำเป็นสำหรับการติดตั้งบนอุปกรณ์เคลื่อนที่ลงในไฟล์ bazelrc ของโปรเจ็กต์ได้ ตั้งแต่ Bazel 8.4.0 เป็นต้นไป คุณจะไม่ต้องใช้แฟล็กเฉพาะการติดตั้งบนอุปกรณ์เคลื่อนที่ (--mode, --mobile_install*) อีกต่อไป คุณอาจต้องใช้แฟล็ก Java ต่างๆ สำหรับภาษาและเวอร์ชันรันไทม์ ขึ้นอยู่กับการกำหนดค่า Java ของเวิร์กสเปซ เครื่องมือย่อยสำหรับการติดตั้งบนอุปกรณ์เคลื่อนที่ต้องใช้ภาษาและระดับรันไทม์ 17 ขึ้นไป

ตอนนี้ "แอปบทแนะนำ Bazel" ควรจะติดตั้งและเปิดใช้โดยอัตโนมัติ

แอปบทแนะนำ Bazel

รูปที่ 2 แอปบทแนะนำ Bazel

ยินดีด้วย คุณเพิ่งติดตั้งแอป Android ที่สร้างด้วย Bazel เป็นครั้งแรก

อ่านเพิ่มเติม

ดูรายละเอียดเพิ่มเติมได้ที่หน้าต่อไปนี้

  • ปัญหาที่เปิดอยู่บน rules_android GitHub
  • ข้อมูลเพิ่มเติมเกี่ยวกับ mobile-install
  • ผสานรวมการขึ้นต่อกันภายนอก เช่น AppCompat, Guava และ JUnit จากที่เก็บ Maven โดยใช้ rules_jvm_external
  • เรียกใช้การทดสอบ Robolectric ด้วยการผสานรวม robolectric-bazel
  • การผสานรวมโค้ด C และ C++ เข้ากับแอป Android ด้วย NDK
  • ดูโปรเจ็กต์ตัวอย่าง Bazel เพิ่มเติมของ

ขอให้สนุกกับการสร้าง