ตัวแทนและสถานะข้อผิดพลาด
จัดการการโหลดและความล้มเหลวอย่างราบรื่น
ตัวแทนและสถานะข้อผิดพลาด เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน
การโหลดไม่ได้เกิดขึ้นทันที
รูปภาพจากเครือข่ายต้องใช้เวลา ในช่วงนั้น UI ของคุณจะแสดง... ไม่มีอะไรเลย หากคุณไม่ได้จัดการ และบางครั้งรูปภาพก็ไม่มาถึง เช่น URL เสีย เซิร์ฟเวอร์หยุดทำงาน หรือผู้ใช้ออฟไลน์
แอปที่ดูเรียบร้อยจะแสดง ตัวแสดงระหว่างโหลด ขณะกำลังโหลด และ ภาพสำรอง เมื่อเกิดข้อผิดพลาด แทนที่จะปล่อยช่องว่างหรือทำให้แอปล่ม Coil ทำให้ทั้งสองอย่างทำได้ง่าย
ในบทเรียนนี้ คุณจะเพิ่มตัวแสดงระหว่างโหลด รูปภาพเมื่อเกิดข้อผิดพลาด และ UI แบบกำหนดเองสำหรับแต่ละสถานะ
ตัวแสดงระหว่างโหลดแบบง่าย
วิธีที่เร็วที่สุดในการเพิ่มตัวแสดงระหว่างโหลดคือส่ง drawable ให้ AsyncImage ผ่านพารามิเตอร์ placeholder โดยใช้ painterResource Coil จะแสดงสิ่งนี้จนกว่ารูปภาพจริงจะโหลดเสร็จ
ใช้ drawable ที่เป็นกลางและมีขนาดเล็ก เช่น กล่องสีเทาหรือภาพเงาของโลโก้
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import coil3.compose.AsyncImage
@Composable
fun ImageWithPlaceholder(url: String) {
AsyncImage(
model = url,
contentDescription = null,
placeholder = painterResource(R.drawable.placeholder_gray)
)
}การเพิ่มรูปภาพเมื่อเกิดข้อผิดพลาด
พารามิเตอร์ error จะแสดง drawable สำรองเมื่อคำขอล้มเหลว นอกจากนี้ยังมี fallback ซึ่งใช้เฉพาะเมื่อ model เป็น null หรือไม่มีข้อมูลให้โหลดเลย
การตั้งค่าทั้งสามอย่าง ได้แก่ placeholder, error และ fallback จะครอบคลุมทุกสถานะการแสดงผลแทบโดยไม่ต้องเขียนโค้ดเพิ่ม
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import coil3.compose.AsyncImage
@Composable
fun RobustImage(url: String?) {
AsyncImage(
model = url,
contentDescription = null,
placeholder = painterResource(R.drawable.placeholder_gray),
error = painterResource(R.drawable.image_broken),
fallback = painterResource(R.drawable.no_image)
)
}ตัวแสดงระหว่างโหลดผ่าน ImageRequest
คุณยังตั้งค่าสถานะเหล่านี้ใน ImageRequest ได้โดยตรง วิธีนี้สะดวกเมื่อคุณสร้างคำขอเพียงครั้งเดียวแล้วนำกลับมาใช้ หรือเมื่อต้องตั้งค่าตัวเลือกคำขออื่น ๆ พร้อมกัน
ฟังก์ชันระดับคำขอรับรหัสทรัพยากร drawable
import android.content.Context
import coil3.request.ImageRequest
import coil3.request.crossfade
import coil3.request.error
import coil3.request.placeholder
fun buildRequest(context: Context, url: String) =
ImageRequest.Builder(context)
.data(url)
.crossfade(true)
.placeholder(R.drawable.placeholder_gray)
.error(R.drawable.image_broken)
.build()UI แบบกำหนดเองด้วย SubcomposeAsyncImage
Drawable ใช้งานได้ดี แต่บางครั้งคุณอาจต้องการตัวหมุน แสงระยิบ หรือข้อความสำหรับแต่ละสถานะ SubcomposeAsyncImage ช่วยให้คุณจัดเตรียมคอมโพสิเบิลจริงสำหรับ loading, error และ success ได้
วิธีนี้ยืดหยุ่นกว่าแต่ใช้ทรัพยากรมากกว่าเล็กน้อย ดังนั้นควรเลือกใช้ตัวแสดงระหว่างโหลดแบบ drawable สำหรับรายการยาว ๆ และเก็บการซับคอมโพสไว้ใช้กับรูปภาพหลัก
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import coil3.compose.SubcomposeAsyncImage
@Composable
fun HeroImage(url: String) {
SubcomposeAsyncImage(
model = url,
contentDescription = "Hero",
loading = { CircularProgressIndicator() },
error = { Text("Could not load image") }
)
}การอ่านสถานะโดยตรง
หากต้องการควบคุมอย่างเต็มที่ ให้ใช้ API rememberAsyncImagePainter และตรวจสอบ state ของมัน สถานะนี้เป็นชนิด sealed ที่มีกรณี Loading, Success, Error และ Empty
วิธีนี้ช่วยให้คุณควบคุมเลย์เอาต์ แอนิเมชัน หรือการวิเคราะห์ข้อมูลของตัวเองตามสิ่งที่เกิดขึ้นได้
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import coil3.compose.AsyncImagePainter
import coil3.compose.rememberAsyncImagePainter
@Composable
fun StateAwareImage(url: String) {
val painter = rememberAsyncImagePainter(model = url)
val state = painter.state.collectAsState().value
when (state) {
is AsyncImagePainter.State.Loading -> { /* show spinner */ }
is AsyncImagePainter.State.Error -> { /* show error UI */ }
else -> Image(painter = painter, contentDescription = null)
}
}การแสดงตัวแสดงระหว่างโหลดแบบแสงระยิบ
รูปแบบที่นิยมคือแสงระยิบ ซึ่งเป็นไล่ระดับสีเทาแบบเคลื่อนไหวที่สื่อว่ากำลังจะมีเนื้อหา คุณสามารถสร้างเวอร์ชันง่าย ๆ ด้วยกล่องสีทึบที่อยู่ด้านหลังสถานะกำลังโหลด
ในที่นี้เราใช้ SubcomposeAsyncImage พร้อมกล่องที่ย้อมสีระหว่างโหลด หากต้องการเอฟเฟกต์เคลื่อนไหว ให้เปลี่ยนกล่องนี้เป็นไลบรารีแสงระยิบ
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import coil3.compose.SubcomposeAsyncImage
@Composable
fun ShimmerImage(url: String) {
SubcomposeAsyncImage(
model = url,
contentDescription = null,
loading = {
androidx.compose.foundation.layout.Box(
Modifier.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceVariant)
)
}
)
}การจัดการ Model ที่เป็น Null หรือว่างเปล่า
หากคุณยังไม่มี URL เช่น ผู้ใช้ที่ยังไม่มีรูปโปรไฟล์จะทำอย่างไร การส่ง null เป็นค่า model จะเรียกใช้ drawable ของ fallback หรือใช้ error หากไม่ได้ตั้งค่า fallback
วิธีนี้ช่วยหลีกเลี่ยงการเขียนเงื่อนไขพิเศษสำหรับ null ในโค้ดของคุณเอง ให้ Coil แสดงรูปประจำตัวเริ่มต้นแทน
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import coil3.compose.AsyncImage
@Composable
fun ProfilePicture(photoUrl: String?) {
// If photoUrl is null, Coil shows the fallback default avatar.
AsyncImage(
model = photoUrl,
contentDescription = "Profile picture",
fallback = painterResource(R.drawable.default_avatar),
error = painterResource(R.drawable.default_avatar)
)
}การฟังข้อผิดพลาดด้วย Listener
บางครั้งคุณต้องตอบสนองในโค้ดเมื่อการโหลดล้มเหลว เช่น บันทึกเหตุการณ์หรือลองใหม่ ImageRequest.Builder รับ listener ที่มีการเรียกกลับเมื่อสำเร็จและเมื่อเกิดข้อผิดพลาด
ให้โค้ดเรียกกลับเหล่านี้ทำงานสั้น ๆ เพราะจะทำงานบนเธรดหลัก
import android.content.Context
import android.util.Log
import coil3.request.ImageRequest
fun loggedRequest(context: Context, url: String) =
ImageRequest.Builder(context)
.data(url)
.listener(
onError = { _, result ->
Log.e("Coil", "Load failed", result.throwable)
},
onSuccess = { _, _ ->
Log.d("Coil", "Loaded $url")
}
)
.build()การย้อมสีและฟิลเตอร์สี
Drawable สำหรับตัวแสดงระหว่างโหลดและข้อผิดพลาดมักดูดีที่สุดเมื่อย้อมสีให้เข้ากับธีม คุณสามารถใช้ ColorFilter กับ AsyncImage ได้ เหมาะอย่างยิ่งสำหรับภาพสำรองสไตล์ไอคอนสีเดียวที่ควรปรับตามโหมดสว่างและมืด
ใช้ฟิลเตอร์เฉพาะกับลักษณะของตัวแสดงระหว่างโหลดหรือข้อผิดพลาดที่ต้องการ ส่วนรูปถ่ายจริงโดยทั่วไปควรไม่ใช้ฟิลเตอร์
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import coil3.compose.AsyncImage
@Composable
fun TintedFallback(url: String?) {
AsyncImage(
model = url,
contentDescription = null,
error = painterResource(R.drawable.ic_image_placeholder),
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurfaceVariant)
)
}คอมโพเนนต์รูปภาพที่ทนทาน
มาประกอบคอมโพเนนต์ที่นำกลับมาใช้ใหม่ได้และจัดการทุกสถานะอย่างเรียบร้อยกัน: พื้นหลังขณะโหลด ภาพสำรองเมื่อเกิดข้อผิดพลาด การเฟดข้าม และการครอบรูป นำไปใส่ในรายการ แล้วไม่ต้องกังวลกับช่องว่างอีกต่อไป
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.crossfade
@Composable
fun ResilientImage(url: String?, size: Int = 96) {
val context = LocalContext.current
AsyncImage(
model = ImageRequest.Builder(context)
.data(url)
.crossfade(true)
.build(),
contentDescription = null,
contentScale = ContentScale.Crop,
placeholder = painterResource(R.drawable.placeholder_gray),
error = painterResource(R.drawable.image_broken),
fallback = painterResource(R.drawable.default_avatar),
modifier = Modifier.size(size.dp)
)
}ตรวจสอบอย่างรวดเร็ว
คุณส่งค่า model = null ให้กับ AsyncImage ตามค่าเริ่มต้น Coil จะแสดง drawable ใด
สรุปทบทวน
คุณทำให้การโหลดรูปภาพจัดการได้อย่างราบรื่นแล้ว ประเด็นสำคัญมีดังนี้:
placeholderจะแสดงระหว่างการโหลด,errorจะแสดงเมื่อโหลดไม่สำเร็จ และfallbackจะแสดงเมื่อ model เป็น null- กำหนดค่าเหล่านี้ให้กับ
AsyncImageหรือImageRequestได้ SubcomposeAsyncImageช่วยให้คุณกำหนด composable จริง เช่น ตัวหมุนรอหรือลักษณะระยิบระยับ แยกตามแต่ละสถานะได้rememberAsyncImagePainterเปิดให้เข้าถึงstateดิบเพื่อควบคุมได้อย่างเต็มที่- ใช้
listenerของคำขอเพื่อบันทึกบันทึกการทำงานหรือตอบสนองต่อผลลัพธ์การโหลด
ถัดไป: การแคชและประสิทธิภาพ เพื่อให้รูปภาพโหลดได้ทันทีในครั้งที่สอง
เรียนรู้ Kotlin ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 36
- บทเรียน
- 152
คำถามที่พบบ่อย
บทเรียน “ตัวแทนและสถานะข้อผิดพลาด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตัวแทนและสถานะข้อผิดพลาด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตัวแทนและสถานะข้อผิดพลาด”
จัดการการโหลดและความล้มเหลวอย่างราบรื่น คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “ตัวแทนและสถานะข้อผิดพลาด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม
ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การโหลดรูปภาพด้วย Coil
- ตัวแทนและสถานะข้อผิดพลาด
- การแคชและประสิทธิภาพ
- การเล่นเสียงและวิดีโอ