คลาส Activity เป็นคอมโพเนนต์ที่สำคัญของแอป Android และวิธีเปิดใช้และรวม
กิจกรรมเข้าด้วยกันเป็นส่วนพื้นฐานของโมเดลแอปพลิเคชันของแพลตฟอร์ม
ระบบ Android จะเริ่มต้นโค้ดในอินสแตนซ์ Activity โดยการเรียกใช้เมธอดเรียกกลับที่เฉพาะเจาะจงซึ่งสอดคล้องกับขั้นตอนที่เฉพาะเจาะจงของวงจรการทำงาน ซึ่งต่างจากกระบวนทัศน์การเขียนโปรแกรมที่เปิดตัวแอปด้วยเมธอด main
เอกสารนี้จะแนะนำแนวคิดของกิจกรรม จากนั้นจะให้คำแนะนำแบบคร่าวๆ เกี่ยวกับวิธีทำงานกับกิจกรรม ดูข้อมูลเพิ่มเติม เกี่ยวกับแนวทางปฏิบัติแนะนำในการออกแบบแอปได้ที่คำแนะนำเกี่ยวกับสถาปัตยกรรมแอป
แนวคิดของกิจกรรม
ประสบการณ์การใช้งานแอปบนอุปกรณ์เคลื่อนที่จะแตกต่างจากแอปบนเดสก์ท็อปตรงที่การโต้ตอบของผู้ใช้กับแอปไม่ได้เริ่มต้นในที่เดียวกันเสมอไป แต่เส้นทางของผู้ใช้มักจะเริ่มต้นแบบไม่แน่นอน ตัวอย่างเช่น หากคุณเปิดแอปอีเมลจากหน้าจอหลัก คุณอาจเห็นรายการอีเมล ในทางตรงกันข้าม หากคุณใช้แอปโซเชียลมีเดียที่เปิดแอปอีเมล คุณอาจไปที่หน้าจอของแอปอีเมลโดยตรงเพื่อเขียนอีเมล
คลาส Activity ออกแบบมาเพื่ออำนวยความสะดวกในกระบวนทัศน์นี้ เมื่อแอปหนึ่ง เรียกใช้อีกแอปหนึ่ง แอปที่เรียกใช้จะเรียกใช้กิจกรรมในอีกแอปหนึ่ง แทนที่จะเรียกใช้แอปทั้งแอป ด้วยวิธีนี้ กิจกรรมจึงทำหน้าที่เป็นจุดแรกเข้าสำหรับการโต้ตอบของแอปกับผู้ใช้ คุณจะใช้กิจกรรมเป็นคลาสย่อยของคลาส Activity
กิจกรรมจะแสดงหน้าต่างที่แอปวาด UI โดยปกติแล้วหน้าต่างนี้จะเต็มหน้าจอ แต่อาจมีขนาดเล็กกว่าหน้าจอและลอยอยู่เหนือ หน้าต่างอื่นๆ
โดยปกติแล้ว กิจกรรมหนึ่งในแอปจะได้รับการระบุเป็นกิจกรรมหลัก ซึ่งเป็นหน้าจอแรกที่จะปรากฏเมื่อผู้ใช้เปิดแอป ในแอป Compose สมัยใหม่ กิจกรรมนี้เป็นกิจกรรมเดียวที่จำเป็น เนื่องจากเป็นโฮสต์ของ Composable ในสถาปัตยกรรมแบบกิจกรรมเดียว แทนที่จะเป็นเจ้าของลำดับชั้นการแสดงผล แทนที่จะให้แอปมีกิจกรรมหลายอย่างสำหรับหน้าจอ Composable ในโฮสต์กิจกรรมจะมีปลายทางการนำทางหลายรายการ
หากต้องการใช้กิจกรรมในแอป คุณต้องลงทะเบียนข้อมูลเกี่ยวกับกิจกรรมในไฟล์ Manifest ของแอป และควรทราบวงจรของกิจกรรม ส่วนที่เหลือของเอกสารนี้จะแนะนำหัวข้อเหล่านี้
การกำหนดค่าไฟล์ Manifest
หากต้องการให้แอปใช้กิจกรรมได้ คุณต้องประกาศกิจกรรมและ แอตทริบิวต์บางอย่างของกิจกรรมในไฟล์ Manifest
ประกาศกิจกรรม
หากต้องการประกาศกิจกรรม ให้เปิดไฟล์ Manifest แล้วเพิ่มองค์ประกอบ <activity>
เป็นองค์ประกอบย่อยขององค์ประกอบ <application> เช่น
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
แอตทริบิวต์ที่จำเป็นเพียงรายการเดียวสำหรับองค์ประกอบนี้คือ android:name ซึ่ง
ระบุชื่อคลาสของกิจกรรม นอกจากนี้ คุณยังเพิ่มแอตทริบิวต์ที่
กำหนดลักษณะกิจกรรม เช่น ป้ายกำกับ ไอคอน หรือธีม UI ได้ด้วย ดูข้อมูลเพิ่มเติมเกี่ยวกับแอตทริบิวต์เหล่านี้และแอตทริบิวต์อื่นๆ ได้ในเอกสารอ้างอิงขององค์ประกอบ <activity>
ประกาศตัวกรอง Intent
ตัวกรอง Intent เป็นฟีเจอร์ที่มีประสิทธิภาพมากของแพลตฟอร์ม Android ซึ่งช่วยให้เปิดกิจกรรมได้ไม่เพียงแต่ตามคำขอที่ชัดเจน เท่านั้น แต่ยังรวมถึงคำขอโดยนัยด้วย เช่น คำขอที่ชัดเจนอาจบอกให้ระบบ "เริ่มกิจกรรมส่งอีเมลในแอป Gmail" ในทางตรงกันข้าม คำขอโดยนัยจะบอกให้ระบบ "เริ่มหน้าจอส่งอีเมลในกิจกรรมใดก็ได้ ที่ทำได้" เมื่อ UI ของระบบถามผู้ใช้ว่าจะใช้แอปใดในการ ทำงาน นั่นคือตัวกรอง Intent ที่ทำงานอยู่
คุณใช้ประโยชน์จากฟีเจอร์นี้ได้โดยการประกาศแอตทริบิวต์ <intent-filter>
ในองค์ประกอบ <activity> คำจำกัดความขององค์ประกอบนี้มีองค์ประกอบ <action> และอาจมีองค์ประกอบ <category>
และ/หรือองค์ประกอบ <data> องค์ประกอบเหล่านี้รวมกันเพื่อระบุ
ประเภทของ Intent ที่กิจกรรมของคุณตอบสนองได้ ตัวอย่างเช่น ข้อมูลโค้ดต่อไปนี้
แสดงวิธีกำหนดค่ากิจกรรมที่ส่งข้อมูลข้อความและอีเมล
และรับคำขอจากกิจกรรมอื่นๆ เพื่อดำเนินการดังกล่าว
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="mailto" />
</intent-filter>
</activity>
ในตัวอย่างนี้ องค์ประกอบ <action> ระบุว่ากิจกรรมนี้ส่งข้อมูล
การประกาศองค์ประกอบ <category> เป็น DEFAULT จะช่วยให้กิจกรรมรับคำขอเปิดใช้ได้ องค์ประกอบ <data> ระบุประเภทของ
ข้อมูลที่กิจกรรมนี้ส่งได้ ข้อมูลโค้ดต่อไปนี้แสดงวิธีเรียกใช้
กิจกรรมที่อธิบายไว้ข้างต้นเพื่อเขียนอีเมล
fun composeEmail(addresses: Array<String>, subject: String) {
val intent = Intent(Intent.ACTION_SENDTO).apply {
data = Uri.parse("mailto:") // Only email apps handle this.
putExtra(Intent.EXTRA_EMAIL, addresses)
putExtra(Intent.EXTRA_SUBJECT, subject)
}
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
หากต้องการให้แอปของคุณทำงานได้ด้วยตัวเองและไม่อนุญาตให้แอปอื่นๆ เปิดใช้งานกิจกรรมของแอป คุณก็ไม่จำเป็นต้องมีตัวกรอง Intent อื่นๆ กิจกรรม ที่คุณไม่ต้องการให้แอปพลิเคชันอื่นๆ เข้าถึงได้ไม่ควรมี ตัวกรอง Intent และคุณสามารถเริ่มกิจกรรมด้วยตนเองได้โดยใช้ Intent ที่ชัดเจน ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่กิจกรรมตอบสนองต่อ Intent ได้ที่Intent และ ตัวกรอง Intent
จัดการ Intent ขาเข้า
ตัวอย่างต่อไปนี้แสดงรูปแบบการจัดการวงจรกิจกรรมขณะ
จัดการ Intent หลายประเภท ได้แก่ การแชร์ข้อความเดียว รูปภาพเดียว และอาร์เรย์รูปภาพหลายรายการ การกำหนดเส้นทางอินพุตที่หลากหลายเหล่านี้ผ่านฟังก์ชัน handleIntent ที่มีศูนย์กลางจะช่วยให้มั่นใจได้ว่าทั้งการดำเนินการ ACTION_SEND และ ACTION_SEND_MULTIPLE จะได้รับการแยกวิเคราะห์อย่างถูกต้องและมอบหมายไปยัง ViewModel เพื่อการอัปเดต UI แบบรีแอ็กทีฟ
class ExampleActivity : ComponentActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleIntent(intent)
setContent {
ComposeApp(viewModel)
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
handleIntent(intent)
}
private fun handleIntent(intent: Intent?) {
when (intent?.action) {
Intent.ACTION_SEND -> {
if ("text/plain" == intent.type) {
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
viewModel.handleText(it) // Update UI to reflect text being shared
}
} else if (intent.type?.startsWith("image/") == true) {
(intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java))?.let {
viewModel.handleImage(it) // Update UI to reflect image being shared
}
}
}
Intent.ACTION_SEND_MULTIPLE -> {
if (intent.type?.startsWith("image/") == true) {
intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)?.let {
viewModel.handleMultipleImages(it) // Update UI to reflect multiple images being shared
}
} else {
// Handle other types
}
}
else -> {
// Handle other intents
}
}
}
}
ประกาศสิทธิ์
คุณใช้แท็ก <activity> ของไฟล์ Manifest เพื่อควบคุมแอปที่เริ่มกิจกรรมหนึ่งๆ ได้
กิจกรรมระดับบนจะเปิดกิจกรรมระดับล่างไม่ได้ เว้นแต่
ทั้ง 2 กิจกรรมจะมีสิทธิ์เดียวกันในไฟล์ Manifest หากคุณประกาศองค์ประกอบ
<uses-permission> สำหรับกิจกรรมหลัก กิจกรรมย่อยแต่ละรายการ
ต้องมีองค์ประกอบ <uses-permission> ที่ตรงกัน
ตัวอย่างเช่น หากแอปของคุณต้องการใช้แอปสมมติชื่อ SocialApp เพื่อ แชร์โพสต์บนโซเชียลมีเดีย SocialApp เองต้องกำหนดสิทธิ์ที่ แอปที่เรียกใช้ต้องมี
<manifest>
<activity android:name="...."
android:permission="com.google.socialapp.permission.SHARE_POST"
/>
จากนั้นแอปของคุณต้องมีกลุ่มสิทธิ์ตรงกับที่ตั้งค่าไว้ในไฟล์ Manifest ของ SocialApp เพื่อให้เรียกใช้ SocialApp ได้
<manifest>
<uses-permission android:name="com.google.socialapp.permission.SHARE_POST" />
</manifest>
ดูข้อมูลเพิ่มเติมเกี่ยวกับสิทธิ์และความปลอดภัยโดยทั่วไปได้ที่รายการตรวจสอบด้านความปลอดภัย
การจัดการวงจรกิจกรรม
กิจกรรมจะเปลี่ยนสถานะต่างๆ ตลอดอายุการใช้งาน คุณใช้ชุดการเรียกกลับเพื่อจัดการการเปลี่ยนสถานะ ส่วนต่อไปนี้จะแนะนำการเรียกกลับเหล่านี้ ในแอป Compose เราไม่แนะนำให้เชื่อมต่อโดยตรง กับโค้ดเรียกกลับเหล่านี้ แต่ให้ใช้ Lifecycle API เพื่อ สังเกตการเปลี่ยนแปลงสถานะแทน ดูข้อมูลเพิ่มเติมได้ที่ผสานรวมวงจรขององค์ประกอบกับ Compose
onCreate
คุณต้องใช้การเรียกกลับนี้ ซึ่งจะเริ่มทำงานเมื่อระบบสร้างกิจกรรม การติดตั้งใช้งานควรเริ่มต้นคอมโพเนนต์ที่จำเป็นของ กิจกรรม เช่น แอปควรสร้างมุมมองและเชื่อมโยงข้อมูลกับรายการที่นี่
ในแอป Compose ให้ใช้การเรียกกลับนี้เพื่อตั้งค่า Composable ของโฮสต์โดยใช้
setContent ดังที่แสดงด้านล่าง
class MyActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Text(text = stringResource(id = R.string.greeting))
}
}
}
เมื่อ onCreate เสร็จสิ้น การเรียกกลับครั้งถัดไปจะเป็น onStart เสมอ
onStart
เมื่อ onCreate ออก กิจกรรมจะเข้าสู่สถานะ "เริ่มแล้ว" และผู้ใช้จะเห็นกิจกรรม Callback นี้มีสิ่งที่เทียบเท่ากับการ
เตรียมการขั้นสุดท้ายของกิจกรรมเพื่อเข้าสู่เบื้องหน้าและกลายเป็น
แบบอินเทอร์แอกทีฟ
onResume
ระบบจะเรียกใช้แฮนเดิลนี้ก่อนที่กิจกรรมจะเริ่มโต้ตอบกับผู้ใช้ ในตอนนี้ กิจกรรมจะอยู่ด้านบนสุดของสแต็กกิจกรรม
และบันทึกข้อมูลจากผู้ใช้ทั้งหมด ฟังก์ชันหลักส่วนใหญ่ของแอปจะได้รับการติดตั้งใช้งานในเมธอด onResume
การเรียกกลับ onPause จะเป็นไปตาม onResume เสมอ
onPause
ระบบจะเรียกใช้ onPause เมื่อกิจกรรมสูญเสียโฟกัสและเข้าสู่สถานะ
หยุดชั่วคราว สถานะนี้จะเกิดขึ้นเมื่อผู้ใช้แตะปุ่มย้อนกลับหรือปุ่ม
ล่าสุด เป็นต้น เมื่อระบบเรียกใช้ onPause สำหรับกิจกรรมของคุณ ในทางเทคนิคหมายความว่ากิจกรรมของคุณยังคงมองเห็นได้บางส่วน แต่ส่วนใหญ่มักเป็นสัญญาณบ่งชี้ว่าผู้ใช้กำลังจะออกจากกิจกรรม และในไม่ช้ากิจกรรมจะเข้าสู่สถานะหยุดหรือกลับมาทำงานต่อ
กิจกรรมในสถานะหยุดชั่วคราวอาจอัปเดต UI ต่อไปหากผู้ใช้ คาดหวังให้ UI อัปเดต ตัวอย่างกิจกรรมดังกล่าว ได้แก่ กิจกรรมที่แสดง หน้าจอแผนที่นำทางหรือมีเดียเพลเยอร์ที่กำลังเล่น แม้ว่ากิจกรรมดังกล่าวจะสูญเสียโฟกัส ไป แต่ผู้ใช้ก็ยังคงคาดหวังให้ UI อัปเดตต่อไป
คุณไม่ควรใช้ onPause เพื่อบันทึกข้อมูลแอปพลิเคชันหรือข้อมูลผู้ใช้ ทำการเรียกเครือข่าย หรือดำเนินการธุรกรรมในฐานข้อมูล ดูข้อมูลเกี่ยวกับการบันทึกข้อมูลได้ที่การบันทึกและกู้คืนสถานะ UI ชั่วคราว
เมื่อ onPause ทำงานเสร็จแล้ว การเรียกกลับครั้งถัดไปจะเป็น onStop หรือ onResume ขึ้นอยู่กับสิ่งที่เกิดขึ้นหลังจากที่กิจกรรม
เข้าสู่สถานะหยุดชั่วคราว
onStop
ระบบจะเรียกใช้ onStop เมื่อผู้ใช้มองไม่เห็นกิจกรรมอีกต่อไป
ซึ่งอาจเกิดขึ้นเนื่องจากระบบกำลังทำลายกิจกรรม กิจกรรมใหม่กำลังเริ่ม หรือกิจกรรมที่มีอยู่กำลังเข้าสู่สถานะ "กลับมาทำงานต่อ" และครอบคลุมกิจกรรมที่หยุดไป ในกรณีเหล่านี้ กิจกรรมที่หยุดแล้วจะไม่ปรากฏอีกเลย
การเรียกกลับครั้งถัดไปที่ระบบเรียกคือ onRestart หากกิจกรรมกลับมาโต้ตอบกับผู้ใช้ หรือ onDestroy หากกิจกรรมนี้สิ้นสุดลงโดยสมบูรณ์
onRestart
ระบบจะเรียกใช้การเรียกกลับนี้เมื่อกิจกรรมในสถานะหยุดกำลังจะรีสตาร์ท
onRestart จะกู้คืนสถานะของกิจกรรมจากเวลาที่หยุด
โดยการเรียกกลับนี้จะตามด้วย onStart เสมอ
onDestroy
ระบบจะเรียกใช้การเรียกกลับนี้ก่อนที่จะทำลายกิจกรรม
โดย Callback นี้จะเป็นรายการสุดท้ายที่กิจกรรมได้รับ โดยปกติแล้วจะมีการใช้ onDestroy เพื่อให้มั่นใจว่าระบบจะปล่อยทรัพยากรทั้งหมดของกิจกรรม
เมื่อกิจกรรมหรือกระบวนการที่มีกิจกรรมนั้นถูกทำลาย
ส่วนนี้เป็นเพียงบทนำเกี่ยวกับหัวข้อนี้ ดูรายละเอียดเพิ่มเติมเกี่ยวกับวงจรกิจกรรมและโค้ดเรียกกลับได้ที่วงจรกิจกรรม