บทแนะนำนี้ครอบคลุมวิธีสร้างแอป 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
ก่อนเริ่มบทแนะนำ ให้ติดตั้งซอฟต์แวร์ต่อไปนี้
- บาเซล หากต้องการติดตั้ง ให้ทำตามวิธีการติดตั้ง
- 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 (พร้อมท์คำสั่ง) | type nul > WORKSPACE |
Windows (PowerShell) | New-Item WORKSPACE -ItemType file |
บาเซล
ตอนนี้คุณจะตรวจสอบได้ว่า 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 Manager ของ Android Studio
สมมติว่าติดตั้ง SDK ไว้ในตำแหน่งเริ่มต้น คุณสามารถใช้คำสั่งต่อไปนี้เพื่อตั้งค่าตัวแปร ANDROID_HOME
ระบบปฏิบัติการ | คำสั่ง |
---|---|
Linux | export ANDROID_HOME=$HOME/Android/Sdk/ |
macOS | export ANDROID_HOME=$HOME/Library/Android/sdk |
Windows (พร้อมท์คำสั่ง) | 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 (พร้อมท์คำสั่ง) | 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
กับทรัพยากรที่ต้องพึ่งพา ไลบรารีเหล่านี้อาจเป็นไฟล์ซอร์สโค้ด (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
จะจัดเก็บไฟล์ต้นทางของตัวกลางที่กฎ 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 (พร้อมท์คำสั่ง) | 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"
รูปที่ 2 แอปบทแนะนำ Bazel
ยินดีด้วย คุณเพิ่งติดตั้งแอป Android ที่สร้าง Bazel แอปแรกของคุณ
โปรดทราบว่าคำสั่งย่อย mobile-install
ยังรองรับ Flag --incremental
ที่ใช้เพื่อทำให้ใช้งานได้เฉพาะส่วนของแอปที่มีการเปลี่ยนแปลงนับตั้งแต่การทำให้ใช้งานได้ครั้งล่าสุด
นอกจากนี้ ยังรองรับ Flag --start_app
เพื่อเริ่มแอปทันทีที่ติดตั้ง
อ่านเพิ่มเติม
ดูรายละเอียดเพิ่มเติมได้ที่หน้าต่อไปนี้
- ปัญหาที่ยังไม่ได้รับการแก้ไขใน GitHub
- ข้อมูลเพิ่มเติมเกี่ยวกับ mobile-install
- ผสานรวมทรัพยากร Dependency ภายนอก เช่น AppCompat, Guava และ JUnit จากที่เก็บของ Maven โดยใช้ rules_jvm_external
- เรียกใช้การทดสอบ Robolectric ด้วยการผสานรวม robolectric-bazel
- การทดสอบแอปด้วยการทดสอบเครื่องมือวัดประสิทธิภาพของ Android
- การผสานรวมโค้ด C และ C++ ในแอป Android ด้วย NDK
- ดูโปรเจ็กต์ตัวอย่างอื่นๆ ของ Bazel
ขอให้สนุกกับการสร้าง