사용자 도구

사이트 도구


android:datastore
datastore

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
android:datastore [2025/05/01 13:42] 이거니맨android:datastore [2025/05/01 14:52] (현재) – 데이터스토어로 저장하는 예제 이거니맨
줄 115: 줄 115:
 ==== 2. 인스턴스 생성하기 ==== ==== 2. 인스턴스 생성하기 ====
  
-"appPreferences"란 이름의 Datastore 인스턴스를 다음과 같이 생성한다. Datastore는 한 앱당 하나의 인스턴스만 싱글톤으로 사용되어야 하므로 호출에 있어서는 굳이 이름이 필요 없을 것이다. 다만, 유지보수 관점에서 기존의 Datastore와는 다른 새로운 Datastore 인스턴스를 만들어야 할 필요도 있을 것이므로 이름은 필요할 것이다. +"appPreferences"란 이름의 Datastore 인스턴스를 다음과 같이 생성한다. Datastore는 한 앱당 하나의 인스턴스만 싱글톤으로 사용되어야 하므로 호출에 있어서는 굳이 이름이 필요 없다고 언뜻 생각할 수도 있다. 다만, 유지보수 관점에서 기존의 Datastore와는 다른 새로운 Datastore 인스턴스를 만들어야 할 필요도 있을 것이므로 이름은 필요할 것이다. 
  
 <code kotlin> <code kotlin>
줄 125: 줄 125:
 Datastore는 [키, 밸류]의 쌍으로 데이터를 저장한다. 이를테면 C#의 Dictionary와 매우 비슷한 구조인 것이다.  Datastore는 [키, 밸류]의 쌍으로 데이터를 저장한다. 이를테면 C#의 Dictionary와 매우 비슷한 구조인 것이다. 
  
-즉, 각 키별로 형식이 존재한다. 이를테면 int값을 저장할 때에는 intPreferencesKey라고 하고, boolean값을 저장할 때에는 booleanPreferencesKey라고 한다. +즉, 각 키별로 형식이 존재한다. 이를테면 int값을 저장할 때에는 intPreferencesKey라고 하고, boolean값을 저장할 때에는 booleanPreferencesKey라고 한다. 자세한 것은 [[https://developer.android.com/reference/kotlin/androidx/datastore/preferences/core/package-summary?_gl=1*1gfysu8*_up*MQ..*_ga*NjkxNzMyNDU2LjE3NDYwNzY0NjQ.*_ga_6HH9YJMN9M*MTc0NjA3NjQ2NC4xLjAuMTc0NjA3NjQ2NC4wLjAuMTU0MDYzMTYwOQ..#top-level-functions|Datastore에 대한 Top-Level functions]]를 참조하라
  
 우리는 boolean값을 "FILTER_ON" 이란 이름으로 저장할 것이다. 따라서 다음과 같이 키를 정의하게 된다.  우리는 boolean값을 "FILTER_ON" 이란 이름으로 저장할 것이다. 따라서 다음과 같이 키를 정의하게 된다. 
줄 131: 줄 131:
 <code kotlin> <code kotlin>
     private val FILTER_ON = booleanPreferencesKey("FilterOn") // string 저장 키값     private val FILTER_ON = booleanPreferencesKey("FilterOn") // string 저장 키값
-</code>+</code>  
 + 
 +==== 4. 키 값 읽기 ==== 
 + 
 +키값은 context.datastore.data.map으로 읽는다.  
 + 
 +<code kotlin> 
 +// Datastore 읽기 
 +// Flow : coroutines.flow import 해야됨 
 +val valueOfFilter : Flow<Boolean> = context.dataStore.data 
 +    .map {preferences -> 
 +        preferences[FILTER_ON] ?: false 
 +    } 
 +</code>  
 + 
 +반환값이 Flow임을 유의하자  
 + 
 +==== 5. 키 값 쓰기 ====  
 + 
 +context.datastore.edit로 키 값을 쓴다.  
 + 
 +<code kotlin> 
 +// Datastore 쓰기 
 +suspend fun setFilterSwitch(switch : Boolean){ 
 +    context.dataStore.edit { preferences-> 
 +        preferences[FILTER_ON] = switch 
 +    } 
 +
 + 
 +</code>  
 + 
 +<WRAP center round tip 90%> 
 +자동적으로 다음이 임포트 되지 않을 수가 있다. 만약 안드로이드 스튜디오가 컴플레인을 하면 다음을 임포트하자  
 + 
 +import androidx.datastore.preferences.core.edit 
 +</WRAP> 
 + 
 + 
  
 ===== 싱글턴으로 만들기 =====  ===== 싱글턴으로 만들기 ===== 
  
 +위의 datastore 인스턴스를 싱글톤으로 단 하나만 존재하게 하기 위하여 MainApplication을 다음과 같이 만들어준다. 
  
 +다음 예제는 database도 생성하는 코드가 같이 있는 것이니 이를 염두에 두고 살펴보자
  
-===== 실제 compose내에서 사용하기 +<file kotlin "MainApplication.kt"> 
 +import android.annotation.SuppressLint 
 +import android.app.Application 
 +import android.content.Context 
 +import androidx.datastore.core.DataStore 
 +import androidx.datastore.preferences.core.Preferences 
 +import androidx.datastore.preferences.preferencesDataStore 
 +import androidx.room.Room.databaseBuilder 
 +import com.dklaw.memorize.database.DataStoreMemorize 
 +import com.dklaw.memorize.database.ScoreDatabase 
 + 
 +class MainApplication : Application() { 
 + 
 +    init { 
 +        instance = this 
 +    } 
 + 
 +    companion object { 
 +        private var instance: MainApplication? = null 
 + 
 +        fun applicationContext() : Context { 
 +            return instance!!.applicationContext 
 +        } 
 + 
 +        lateinit var scoreDatabase: ScoreDatabase 
 + 
 +        // Datastore 변수 
 +        @SuppressLint("StaticFieldLeak"
 +        private lateinit var dataStore: DataStoreMemorize 
 + 
 +        fun getThis() : MainApplication { 
 +            return instance!! 
 +        } 
 + 
 +        fun  getDateStore() : DataStoreMemorize = dataStore 
 +    } 
 + 
 +    override fun onCreate() { 
 +        super.onCreate() 
 +        // initialize for any 
 + 
 +        // Use ApplicationContext. 
 +        val context: Context = MainApplication.applicationContext() 
 + 
 +        // Datastore single Instance 
 +        dataStore = DataStoreMemorize(this) 
 + 
 +        // Database Initialize 
 +        scoreDatabase = databaseBuilder( 
 +            applicationContext, 
 +            ScoreDatabase::class.java, 
 +            ScoreDatabase.NAME 
 +        ).build() 
 +    } 
 +
 +</file> 
 + 
 +===== 실제 compose내에서 사용하기 =====  
 + 
 +==== 1. 읽기 ==== 
 + 
 +다음과 같이 싱글톤으로 불러온 다음 헬퍼클래스의 읽이 함수를 호출한다.  
 + 
 +<code kotlin> 
 +    // 데이터 스토어 세팅 값 
 +    val isFiltered by MainApplication.getDateStore().valueOfFilter.collectAsState(initial = false) 
 +</code>  
 + 
 + 
 +Flow로 받아오므로 colletAsState로 값을 받아온 것을 알 수 있다.  
 + 
 +==== 2. 쓰기 ==== 
 + 
 +다음과 같이 코루틴을 통해 저장한다.  
 + 
 +<code kotlin> 
 +// 스위치 버튼, 코루틴 
 +@Composable 
 +fun switchButton(modifier: Modifier) { 
 + 
 +    val coroutineScope = rememberCoroutineScope() 
 +    val isFiltered by MainApplication.getDateStore().valueOfFilter.collectAsStateWithLifecycle(initialValue = false) 
 + 
 +    Row(modifier = modifier, horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) { 
 +        Text(text = if (isFiltered) {"필터"} else {"모두"}, style = MaterialTheme.typography.titleMedium, modifier = Modifier 
 +            .padding(vertical = 4.dp) 
 +            .weight(0.5f), textAlign = TextAlign.Center) 
 +        Switch( 
 +            checked = isFiltered, 
 +            onCheckedChange = { 
 + 
 +                coroutineScope.launch { MainApplication.getDateStore().setFilterSwitch(!isFiltered) } 
 + 
 +            }, 
 +            modifier = Modifier 
 +                .weight(0.5f) 
 +                .semantics { this.contentDescription = "Filter by completion" }, 
 +            thumbContent = if (isFiltered) { 
 +                { 
 +                    Icon( 
 +                        imageVector = Icons.Filled.Check, 
 +                        contentDescription = "Checked", 
 +                        modifier = Modifier.size(SwitchDefaults.IconSize), 
 +                    ) 
 +                } 
 +            } else { 
 +                {   Icon( 
 +                    imageVector = Icons.Filled.Close, 
 +                    contentDescription = "UnChecked", 
 +                    modifier = Modifier.size(SwitchDefaults.IconSize), 
 +                )} 
 +            } 
 +        ) 
 +    } 
 +
 +</code>
android/datastore.1746074525.txt.gz · 마지막으로 수정됨: 2025/05/01 13:42 저자 이거니맨