본문 바로가기

Android/기능

[Android] SharedPreference에 ArrayList 넣기

저 같은 경우는 앱 설정에서 설정된 정보를 SharedPreference에 담을 수 있도록 프로그램을 짜는 경우가 종종 있었습니다. 맨날 String, Int와 같은 자료만 담다가 ArrayList를 담을 일이 생겼는데, 기본적으로 SharedPreference에 ArrayList를 담을 방법은 존재하지 않았습니다. 

 

해결 방법은 간단했습니다.

정보를 저장할 때는 (set) : ArrayList 데이터를 JSON 데이터로 변환 후, 그 정보를 String으로 저장

정보를 받아올 때는 (get) : String으로 저장된 JSON 데이터를 하나씩 꺼내와서 ArrayList로 저장 후 반환

 

즉, JSON 데이터 형식을 매개로 ArrayList와 String의 자유로운 변환을 통해 값을 만질 수 있는 것입니다.

 

다음은 예제입니다.

String 관련 예제도 추가로 넣었으니 비교하면서 보시면 됩니다.

 

 

 

 

 

1. String getter와 setter 및 ArrayList getter와 setter

 

class SharedPreference(context: Context) {
    val preference: SharedPreferences = context.getSharedPreferences("preference", 0)

    // String 조작하는 SharedPreference
    var stringPreference: String
        get() = preference.getString("stringPreference", "default value")!!
        set(value) = preference.edit().putString("stringPreference", value).apply()

    // ArrayList 조작하는 SharedPreference
    var arrayListPreference: ArrayList<String>
        get() {
            // JSON 데이터를 String으로 저장했으므로, String의 값을 받아옵니다.
            val json = preference.getString("arrayListPreference", null)
            val arrayList = ArrayList<String>() // 반환 할 arrayList를 만들어줍니다.
            if(json != null) {
                try {
                    val jsonArray = JSONArray(json) // JSONArray로 저장했던 값을 변환합니다.
                    // JSON의 값들을 하나씩 arrayList로 옮깁니다.
                    for(i in 0 until jsonArray.length()) arrayList.add(jsonArray.optString(i))
                } catch(e: JSONException) {
                    e.printStackTrace()
                }
            }
            // arrayList를 반환합니다.
            return arrayList
        }

        // 여기서 values는 arrayList입니다.
        set(values) {
            val editor = preference.edit()
            val jsonArray = JSONArray() // JSONArray를 미리 만들어주고
            for(value in values) {
                jsonArray.put(value) // arrayList의 값들을 JSONArray에 넣어줍니다.
            }
            if(values.isNotEmpty()) {
                // 비어있는 ArrayList가 아니라면 JSON으로 변환된 값을 String으로 바꾸어 SharedPreference로 저장합니다.
                editor.putString("arrayListPreference", jsonArray.toString())
            } else {
                editor.putString("arrayListPreference", null)
            }
            editor.apply()
        }

}

 

 

 

 

2. App class

 

class App: Application() {

    companion object {
        lateinit var preference: SharedPreference
    }

    override fun onCreate() {
        preference = SharedPreference(applicationContext)
        super.onCreate()
    }
}

 

 

 

 

3. Manifest에 .App 추가

 

..
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   ../>

    <application
        android:name=".App"
        android:allowBackup="true"
        ..>
        <activity android:name=".MainActivity"..

</manifest>

 

 

 

 

4. 테스트 레이아웃 구성 (activity_main.xml)

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingTop="24dp"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="String Test"
        android:textSize="20sp"
        android:gravity="center"/>

    <EditText
        android:id="@+id/string_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="문자열을 입력해주세요." />

    <Button
        android:id="@+id/string_set"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="SharedPreference String 저장하기"
        android:textAllCaps="false"/>

    <TextView
        android:id="@+id/string_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:gravity="center"/>

    <Button
        android:id="@+id/string_get"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="SharedPreference String 불러오기"
        android:textAllCaps="false"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="ArrayList Test"
        android:textSize="20sp"
        android:gravity="center"
        android:layout_marginTop="48dp"/>

    <EditText
        android:id="@+id/arraylist_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="문자열을 입력해주세요." />

    <Button
        android:id="@+id/arraylist_set"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="SharedPreference ArrayList 저장하기"
        android:textAllCaps="false"/>

    <TextView
        android:id="@+id/arraylist_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:gravity="center"/>

    <Button
        android:id="@+id/arraylist_get"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="SharedPreference ArrayList 불러오기"
        android:textAllCaps="false"/>


</LinearLayout>

 

 

 

 

5. MainActivity.kt

 

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // String Test

        // set
        string_set.setOnClickListener {
            App.preference.stringPreference = string_input.text.toString()
        }

        // get
        string_get.setOnClickListener {
            string_text.text = App.preference.stringPreference
        }




        // ArrayList Test

        // set
        arraylist_set.setOnClickListener {
            // , 를 기준으로 문자열을 나누어 ArrayList로 만들어줍니다.
            val arrayList = arraylist_input.text.split(",") as ArrayList<String>
            App.preference.arrayListPreference = arrayList
        }

        // get
        arraylist_get.setOnClickListener {
            // ArrayList로 값을 받아온 뒤, 각 원소의 인덱스와 값을 TextView에 순서대로 띄웁니다.
            val arrayList = App.preference.arrayListPreference
            val builder = StringBuilder()
            for((index, value) in arrayList.withIndex()) {
                builder.append("$index: $value, ")
            }
            arraylist_text.text = builder.toString()
        }
    }
}

 

 

 

테스트 화면