ค่ากำหนดของ DataStore
แทนที่ SharedPreferences ด้วยไลบรารี DataStore รุ่นใหม่ อ่านข้อมูลในรูปแบบ Kotlin Flow เขียนข้อมูลด้วย edit{} และจัดการข้อผิดพลาดอย่างปลอดภัย
ค่ากำหนดของ DataStore เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 5 จากทั้งหมด 6 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 6 บทเรียน
เหตุใดจึงใช้ DataStore
DataStore เป็นสิ่งทดแทนสมัยใหม่ของ SharedPreferences โดยแก้ปัญหาที่สำคัญหลายประการ:
- SharedPreferences บล็อกเธรด UI — DataStore ทำงานแบบอะซิงโครนัสอย่างสมบูรณ์
- SharedPreferences อาจทำให้เกิดข้อยกเว้นที่ไม่ได้จัดการ — DataStore จัดการข้อผิดพลาดผ่าน Flow
- DataStore ปลอดภัยด้านชนิดข้อมูล (Preferences) หรือ ปลอดภัยด้านสคีมา (Proto)
- ทำงานร่วมกับ Kotlin Coroutines และ Flow ได้โดยตรง
DataStore สองประเภท
เลือกประเภทที่เหมาะกับกรณีการใช้งานของคุณ:
- Preferences DataStore — คู่คีย์-ค่า ไม่จำเป็นต้องมีสคีมา ตั้งค่าได้ง่ายที่สุด เหมาะสำหรับการตั้งค่าแอปและค่ากำหนดของผู้ใช้
- Proto DataStore — ออบเจ็กต์ที่มีประเภทข้อมูลโดยใช้ Protocol Buffers จำเป็นต้องมีไฟล์สคีมา .proto เหมาะเมื่อคุณมีข้อมูลที่มีโครงสร้าง
บทเรียนนี้ครอบคลุม Preferences DataStore
การเพิ่ม Dependency
เพิ่ม DataStore ลงใน app/build.gradle:
// app/build.gradle
dependencies {
implementation 'androidx.datastore:datastore-preferences:1.1.1'
// Coroutines (likely already in your project)
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
}การสร้างอินสแตนซ์ DataStore
สร้าง DataStore เพียงครั้งเดียวโดยใช้ตัวแทนระดับบนสุด โดยทั่วไปจะทำในไฟล์แยกต่างหาก:
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStore
// Top-level property — creates a single DataStore instance per Context
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_prefs")การกำหนดคีย์
คีย์เป็นออบเจ็กต์ที่ปลอดภัยด้านประเภทข้อมูล ไม่ใช่สตริงธรรมดา ให้สร้างคีย์ด้วยฟังก์ชันโรงงานที่ถูกต้อง:
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
object PreferencesKeys {
val DARK_MODE = booleanPreferencesKey("dark_mode")
val USER_NAME = stringPreferencesKey("user_name")
val LAUNCH_COUNT = intPreferencesKey("launch_count")
}การเขียนข้อมูล
เขียนข้อมูลภายในโครูทีนโดยใช้ edit { }:
import androidx.datastore.preferences.core.edit
// In a ViewModel or Repository:
suspend fun saveDarkMode(enabled: Boolean) {
context.dataStore.edit { prefs ->
prefs[PreferencesKeys.DARK_MODE] = enabled
}
}
suspend fun incrementLaunchCount() {
context.dataStore.edit { prefs ->
val current = prefs[PreferencesKeys.LAUNCH_COUNT] ?: 0
prefs[PreferencesKeys.LAUNCH_COUNT] = current + 1
}
}การอ่านข้อมูลด้วย Flow
DataStore เปิดเผยข้อมูลในรูปแบบ Flow ใช้ map เพื่อดึงค่าที่ต้องการ:
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
val darkModeFlow: Flow<Boolean> = context.dataStore.data
.map { prefs ->
prefs[PreferencesKeys.DARK_MODE] ?: false // default = false
}
val userNameFlow: Flow<String> = context.dataStore.data
.map { prefs ->
prefs[PreferencesKeys.USER_NAME] ?: "Guest"
}การรวบรวมข้อมูลใน ViewModel
เปิดเผย DataStore Flow จาก ViewModel โดยใช้ stateIn เพื่อรวบรวมข้อมูลอย่างมีประสิทธิภาพ:
class SettingsViewModel(private val repo: SettingsRepository) : ViewModel() {
val isDarkMode: StateFlow<Boolean> = repo.darkModeFlow
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = false
)
fun toggleDarkMode(enabled: Boolean) {
viewModelScope.launch {
repo.saveDarkMode(enabled)
}
}
}การสังเกตข้อมูลใน Activity/Fragment
รวบรวม StateFlow ใน UI โดยใช้ lifecycleScope.launch:
// In Fragment:
lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.isDarkMode.collect { darkMode ->
binding.switchDarkMode.isChecked = darkMode
AppCompatDelegate.setDefaultNightMode(
if (darkMode) AppCompatDelegate.MODE_NIGHT_YES
else AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
)
}
}
}การจัดการข้อผิดพลาด
DataStore จะส่ง IOException หากไฟล์เสียหาย ให้ดักจับข้อผิดพลาดในไปป์ไลน์ของ Flow:
import kotlinx.coroutines.flow.catch
import java.io.IOException
val safeFlow: Flow<Boolean> = context.dataStore.data
.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences()) // return defaults
} else {
throw exception
}
}
.map { prefs ->
prefs[PreferencesKeys.DARK_MODE] ?: false
}DataStore เทียบกับ SharedPreferences
สรุปเหตุผลที่ DataStore เหนือกว่า:
- DataStore อ่านและเขียนข้อมูลบนเธรดเบื้องหลังโดยอัตโนมัติ — ไม่มีความเสี่ยงเกิด ANR
apply()ของ SharedPreferences อาจล้มเหลวโดยไม่แสดงข้อผิดพลาด ส่วน DataStore จะส่งต่อข้อผิดพลาดผ่าน Flow- DataStore ตอบสนองต่อการเปลี่ยนแปลง — UI จะอัปเดตโดยอัตโนมัติเมื่อข้อมูลเปลี่ยน
- SharedPreferences ไม่มีเส้นทางสำหรับการย้ายข้อมูล ส่วน DataStore มี
SharedPreferencesMigrationในตัว
ตรวจสอบความเข้าใจ
กลไกหลักที่ DataStore ใช้เพื่อเปิดเผยข้อมูลให้ส่วนอื่นของแอปคืออะไร
ทบทวน: Preferences ของ DataStore
DataStore เป็นวิธีสมัยใหม่สำหรับจัดเก็บข้อมูลอย่างง่ายให้คงอยู่:
- เพิ่ม Dependency
datastore-preferences - สร้างอินสแตนซ์เดียวด้วยตัวแทน
preferencesDataStore - กำหนดคีย์ที่ปลอดภัยด้านประเภทข้อมูลด้วย
stringPreferencesKey,booleanPreferencesKeyและอื่น ๆ - เขียนข้อมูลด้วย
dataStore.edit { }ภายในโครูทีน - อ่านข้อมูลเป็น
Flowด้วยdataStore.data.map { } - จัดการ
IOExceptionด้วย.catch { emit(emptyPreferences()) }
ถัดไป: สร้างตัวปรับรายการที่มีประสิทธิภาพด้วย DiffUtil
คำถามที่พบบ่อย
บทเรียน “ค่ากำหนดของ DataStore” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ค่ากำหนดของ DataStore” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 6 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ค่ากำหนดของ DataStore”
แทนที่ SharedPreferences ด้วยไลบรารี DataStore รุ่นใหม่ อ่านข้อมูลในรูปแบบ Kotlin Flow เขียนข้อมูลด้วย edit{} และจัดการข้อผิดพลาดอย่างปลอดภัย คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 5 จากทั้งหมด 6 บทเรียน
บทเรียน “ค่ากำหนดของ DataStore” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม
ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คอลเลกชัน Kotlin
- พื้นฐาน RecyclerView
- เหตุการณ์คลิกใน RecyclerView
- SharedPreferences
- ค่ากำหนดของ DataStore
- อะแดปเตอร์และ DiffUtil