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

รายงานปัญหา ดูซอร์สโค้ด รุ่น Nightly · 8.0 7.4 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

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

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

  • ตั้งค่าสภาพแวดล้อมโดยการติดตั้ง Bazel และ Android Studio รวมถึงดาวน์โหลดโปรเจ็กต์ตัวอย่าง
  • ตั้งค่า workspace ของ Bazel ที่มีซอร์สโค้ดสําหรับแอปและไฟล์ WORKSPACE ที่ระบุระดับบนสุดของไดเรกทอรี workspace
  • อัปเดตไฟล์ WORKSPACE ให้อ้างอิงถึงทรัพยากร 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 โปรเจ็กต์ และมีไฟล์ WORKSPACE ที่รูท

ไฟล์ WORKSPACE อาจว่างเปล่าหรือมีการอ้างอิงถึงทรัพยากรภายนอกที่จําเป็นสําหรับการสร้างโปรเจ็กต์

ก่อนอื่น ให้เรียกใช้คําสั่งต่อไปนี้เพื่อสร้างไฟล์ WORKSPACE ว่าง

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

ใช้งาน Bazel

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

bazel info workspace

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

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

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

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

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

android_sdk_repository(name = "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 SDK, ระดับ API และเวอร์ชันของเครื่องมือสร้างที่จะใช้ได้โดยใส่แอตทริบิวต์ path, api_level และ build_tools_version หากไม่ได้ระบุ api_level และ build_tools_version กฎ android_sdk_repository จะใช้เวอร์ชันล่าสุดที่เกี่ยวข้องซึ่งมีอยู่ใน SDK คุณสามารถระบุการผสมผสานแอตทริบิวต์เหล่านี้ได้ ตราบใดที่แอตทริบิวต์ดังกล่าวมีอยู่ใน SDK เช่น

android_sdk_repository(
    name = "androidsdk",
    path = "/path/to/Android/sdk",
    api_level = 25,
    build_tools_version = "30.0.3"
)

ใน Windows โปรดทราบว่าแอตทริบิวต์ path ต้องใช้เส้นทางแบบผสม กล่าวคือ เส้นทาง Windows ที่มีเครื่องหมายทับ

android_sdk_repository(
    name = "androidsdk",
    path = "c:/path/to/Android/sdk",
)

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

android_ndk_repository(name = "androidndk")

ระบบจะอนุมานเส้นทางไปยัง Android NDK จากตัวแปรสภาพแวดล้อม ANDROID_NDK_HOME โดยค่าเริ่มต้น ซึ่งคล้ายกับ android_sdk_repository นอกจากนี้ คุณยังระบุเส้นทางอย่างชัดเจนได้ด้วยแอตทริบิวต์ path ใน android_ndk_repository

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

api_level คือเวอร์ชันของ Android API ที่ SDK และ NDK กำหนดเป้าหมาย เช่น 23 สำหรับ Android 6.0 และ 25 สำหรับ Android 7.1 หากไม่ได้ตั้งค่าอย่างชัดเจน api_level จะมีค่าเริ่มต้นเป็นระดับ API สูงสุดที่ใช้ได้สำหรับ android_sdk_repository และ android_ndk_repository

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

สร้างไฟล์ BUILD

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

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

โปรดทราบว่าลําดับชั้นของแพ็กเกจ 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:

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 คุณจะอ้างอิงกฎโดยใช้ชื่อนี้เป็นทรัพยากรในกฎ android_binary

เพิ่มกฎ android_binary

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

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

src/main/BUILD:

android_binary(
    name = "app",
    manifest = "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 จะใส่เอาต์พุตของทั้งการดำเนินการบิลด์ขั้นกลางและขั้นสุดท้ายไว้ในชุดไดเรกทอรีเอาต์พุตต่อผู้ใช้ต่อเวิร์กสเปซ ไดเรกทอรีเหล่านี้เป็นลิงก์สัญลักษณ์จากตำแหน่งต่อไปนี้ที่ระดับบนสุดของไดเรกทอรีโปรเจ็กต์ โดยที่ WORKSPACE คือ

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

Bazel จะจัดเก็บไฟล์ .apk ของ Android ที่สร้างขึ้นโดยใช้กฎ 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

ต่อไป ให้ค้นหาและเปิด "แอปบทแนะนำ Bazel"

แอปบทแนะนำ Bazel

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

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

โปรดทราบว่าคำสั่งย่อย mobile-install ยังรองรับ Flag --incremental ที่ใช้เพื่อทำให้ใช้งานได้เฉพาะส่วนของแอปที่มีการเปลี่ยนแปลงนับตั้งแต่การทำให้ใช้งานได้ครั้งล่าสุด

นอกจากนี้ยังรองรับ Flag --start_app เพื่อเริ่มแอปทันทีที่ติดตั้ง

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

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

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