0Pricing
Android Academy · บทเรียน

ค่ากำหนดของ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. คอลเลกชัน Kotlin
  2. พื้นฐาน RecyclerView
  3. เหตุการณ์คลิกใน RecyclerView
  4. SharedPreferences
  5. ค่ากำหนดของ DataStore
  6. อะแดปเตอร์และ DiffUtil
← กลับไปที่ Android Academy