บทแนะนำนี้กล่าวถึงวิธีสร้างแอป Android แบบง่ายๆ โดยใช้ Bazel
Bazel รองรับการสร้างแอป Android โดยใช้กฎของ Android
บทแนะนำนี้มีไว้สำหรับผู้ใช้ Windows, macOS และ Linux และไม่จำเป็นต้องมีประสบการณ์ในการพัฒนาแอป Bazel หรือ Android คุณไม่จำเป็นต้องเขียนโค้ด Android ในบทแนะนำนี้
สิ่งที่คุณจะได้เรียนรู้
ในบทแนะนำนี้ คุณจะได้เรียนรู้วิธีต่อไปนี้
- ตั้งค่าสภาพแวดล้อมโดยการติดตั้ง Bazel และ Android Studio และดาวน์โหลดโปรเจ็กต์ตัวอย่าง
- ตั้งค่าพื้นที่ทำงานของ Bazel ที่มีซอร์สโค้ดสำหรับแอปและไฟล์
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
อาจว่างเปล่าหรืออาจมีการอ้างอิงไปยังทรัพยากร Dependency ภายนอกที่จำเป็นต่อการสร้างโปรเจ็กต์
ก่อนอื่น ให้เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างไฟล์ 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
เพื่อสร้างแอป ซึ่งหมายความว่าคุณต้องเพิ่มข้อมูลบางอย่างลงในไฟล์
WORKSPACE
เพื่อให้ Bazel ทราบว่าจะหาเจอได้จากที่ใด
เพิ่มบรรทัดต่อไปนี้ในไฟล์ WORKSPACE
android_sdk_repository(name = "androidsdk")
ซึ่งจะใช้ Android SDK ในเส้นทางที่อ้างอิงโดยตัวแปรสภาพแวดล้อม ANDROID_HOME
และจะตรวจหา API ระดับสูงสุดและเครื่องมือสร้างเวอร์ชันล่าสุดที่ติดตั้งภายในตำแหน่งนั้นโดยอัตโนมัติ
คุณตั้งค่าตัวแปร ANDROID_HOME
เป็นตําแหน่งของ Android SDK ได้ ค้นหาเส้นทางไปยัง SDK ที่ติดตั้งโดยใช้เครื่องมือจัดการ SDK ของ 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" |
คำสั่งข้างต้นจะกำหนดตัวแปรสำหรับเซสชัน Shell ปัจจุบันเท่านั้น หากต้องการให้มีผลถาวร ให้เรียกใช้คำสั่งต่อไปนี้
ระบบปฏิบัติการ | คำสั่ง |
---|---|
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 กับ 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
และทรัพยากร Dependency ของทรัพยากรเหล่านั้น ทรัพยากร Dependency เหล่านี้อาจเป็นไฟล์ต้นฉบับ (Java, C++) ในพื้นที่ทำงาน หรือเอาต์พุตของบิลด์อื่นๆ ไฟล์ BUILD
เขียนด้วยภาษาที่ชื่อว่า Starlark
ไฟล์ BUILD
เป็นส่วนหนึ่งของแนวคิดใน Bazel ซึ่งเรียกว่าลำดับชั้นของแพ็กเกจ
ลำดับชั้นของแพ็กเกจเป็นโครงสร้างเชิงตรรกะที่วางซ้อนโครงสร้างไดเรกทอรีในพื้นที่ทำงาน แพ็กเกจแต่ละรายการคือไดเรกทอรี (และไดเรกทอรีย่อย) ที่มีชุดไฟล์ต้นฉบับที่เกี่ยวข้องและไฟล์ BUILD
แพ็กเกจนี้ยังประกอบด้วยไดเรกทอรีย่อย ยกเว้นรายการที่มีไฟล์ BUILD
ของตนเอง ชื่อแพ็กเกจคือเส้นทางไปยังไฟล์ BUILD
ที่สัมพันธ์กับ WORKSPACE
โปรดทราบว่าลำดับชั้นแพ็กเกจของ Bazel นั้นแตกต่างจากลำดับชั้นแพ็กเกจ Java ของไดเรกทอรีแอป Android ที่มีไฟล์ BUILD
แม้ว่าจะมีการจัดระเบียบไดเรกทอรีให้เหมือนกันก็ตาม
สำหรับแอป Android แบบง่ายในบทแนะนำนี้ ไฟล์ต้นฉบับใน src/main/
จะมีแพ็กเกจ Bazel รายการเดียว โปรเจ็กต์ที่ซับซ้อนมากขึ้นอาจมีแพ็กเกจที่ฝังอยู่หลายแพ็กเกจ
เพิ่มกฎ android_library
ไฟล์ BUILD
มีการประกาศประเภทต่างๆ สำหรับ Bazel ประเภทที่สำคัญที่สุดคือกฎการสร้าง ซึ่งจะบอกวิธีสร้างเอาต์พุตซอฟต์แวร์ระดับกลางหรือขั้นสุดท้ายจากชุดไฟล์ต้นฉบับหรือทรัพยากร Dependency อื่นๆ 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
จะจัดเก็บไฟล์แหล่งที่มาที่เป็นตัวกลางที่สร้างขึ้นโดยกฎ Bazelbazel-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 ก่อนการติดตั้งใช้งาน นอกจากนี้ คุณยังเลือกติดตั้งแอปในโปรแกรมจำลอง Android ที่รวมอยู่ใน Android Studio ได้ด้วย โปรดตรวจสอบว่าโปรแกรมจำลองกำลังทำงานอยู่ก่อนเรียกใช้คำสั่งด้านล่าง
ป้อนข้อมูลต่อไปนี้
bazel mobile-install //src/main:app
จากนั้นค้นหาและเปิด "แอปบทแนะนำ Bazel"
รูปที่ 2 แอปบทแนะนำ Bazel
ยินดีด้วย คุณเพิ่งติดตั้งแอป Android ที่ Bazel สร้างขึ้นเป็นครั้งแรก
โปรดทราบว่าคำสั่งย่อย mobile-install
ยังรองรับแฟล็ก --incremental
ที่ใช้เพื่อทำให้ใช้งานได้เฉพาะส่วนของแอปที่มีการเปลี่ยนแปลงนับตั้งแต่การทำให้ใช้งานได้ครั้งล่าสุด
และยังรองรับแฟล็ก --start_app
เพื่อให้เริ่มแอปได้ทันทีขณะติดตั้ง
อ่านเพิ่มเติม
ดูรายละเอียดเพิ่มเติมได้ที่หน้าเหล่านี้
- ปัญหาที่ยังไม่ดำเนินการใน GitHub
- ดูข้อมูลเพิ่มเติมเกี่ยวกับการติดตั้งบนอุปกรณ์เคลื่อนที่
- ผสานรวมทรัพยากร Dependency ภายนอก เช่น AppCompat, Guava และ JUnit จากที่เก็บ Maven โดยใช้ rules_jvm_external
- ทดสอบ Robolectric ด้วยการผสานการทำงาน robolectric-bazel
- การทดสอบแอปด้วยการทดสอบการใช้เครื่องมือ Android
- การผสานรวมโค้ด C และ C++ ในแอป Android ด้วย NDK
- ดูโปรเจ็กต์ตัวอย่างอื่นๆ ของ Bazel ต่อไปนี้
ขอให้สนุกกับการสร้าง