Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

안드로이드 SharedPreferences에서 apply() 사용법 – 예제와 함께 배우기


Android SharedPreferences란 무엇인가?

apply() 메서드를 본격적으로 살펴보기 전에, 먼저 Android에서 SharedPreferences가 무엇인지 짚고 넘어가겠습니다. SharedPreferences를 활용하면 데이터를 키(Key)와 값(Value) 쌍 형태로 손쉽게 저장하거나 불러올 수 있습니다. SharedPreferences에서 사용할 수 있는 대표적인 메서드는 다음과 같습니다.

  • edit() – SharedPreferences 값을 편집하기 위한 Editor 객체를 가져옵니다.

  • commit() – 변경된 값을 XML 파일에 동기적으로 저장(commit)합니다.

  • apply() – Editor에서 수정한 내용을 SharedPreferences에 반영합니다.

  • remove(String key) – 지정한 키와 해당 값을 SharedPreferences에서 제거합니다.

  • put() – 키와 값을 SharedPreferences XML 파일에 저장합니다.

SharedPreferences 생성 문법 예시

final SharedPreferences sharedPreferences=getSharedPreferences("USER",MODE_PRIVATE);

위 코드는 USER.xml이라는 이름의 SharedPreferences 파일을 생성하는 예입니다. MODE_PRIVATE 모드로 선언했기 때문에 이 환경설정 파일은 해당 앱에서만 접근할 수 있으며, 다른 애플리케이션은 열람할 수 없습니다.

apply() 메서드의 동작 방식과 특징

apply()는 변경 사항을 메모리(in-memory)에 즉시 반영한 뒤, 영구 저장소(디스크)에는 비동기(asynchronous) 방식으로 기록하도록 예약합니다. 이 때문에 저장 작업이 완료될 때까지 UI 스레드가 차단되지 않으므로, 동기 방식으로 동작하는 commit()에 비해 화면 끊김이나 ANR(Application Not Responding) 발생 위험을 줄일 수 있습니다.

참고로 commit()은 저장 성공 여부를 boolean 값으로 반환하지만, apply()는 별도의 반환값이 없다는 차이점도 있습니다. 따라서 저장 결과를 즉시 확인할 필요가 없는 일반적인 경우라면 apply() 사용이 권장됩니다.

아래 예제는 Android SharedPreferences에서 apply()를 사용하는 방법을 단계별로 보여줍니다.

1단계 – Android Studio에서 File ⇒ New Project를 선택하고, 필요한 정보를 모두 입력하여 새 프로젝트를 생성합니다.

2단계 – res/layout/activity_main.xml에 아래 코드를 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity"
    tools:layout_editor_absoluteY="81dp">

    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginTop="8dp"
        android:autofillHints=""
        android:hint="NAME"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="0dp" />

    <EditText
        android:id="@+id/address"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="84dp"
        android:hint="Phone Number"
        android:importantForAutofill="no"
        android:inputType=""
        app:layout_constraintTop_toTopOf="@+id/name"
        tools:layout_editor_absoluteX="16dp"
        tools:targetApi="o" />

    <Button
        android:id="@+id/button"
        android:layout_width="108dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="120dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:gravity="center_horizontal"
        android:text="Save"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.503"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/address" />

    <Button
        android:id="@+id/read"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="88dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:gravity="center_horizontal"
        android:text="read"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

    <TextView
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="184dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="result"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />
</android.support.constraint.ConstraintLayout>

위 XML 레이아웃에는 이름(name)과 주소(address)를 입력받는 두 개의 EditText가 포함되어 있습니다. 사용자가 Save 버튼을 누르면 입력한 값이 SharedPreferences에 저장되고, read 버튼을 누르면 SharedPreferences에서 값을 읽어와 화면에 표시합니다.

3단계 – src/MainActivity.java에 아래 코드를 추가합니다.

package com.example.andy.myapplication;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final SharedPreferences sharedPreferences=getSharedPreferences("USER",MODE_PRIVATE);
        final EditText name=findViewById(R.id.name);
        final EditText address=findViewById(R.id.address);
        final TextView result=findViewById(R.id.result);
        Button save=findViewById(R.id.button);
        Button read=findViewById(R.id.read);
        read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                result.setText("Name is "+sharedPreferences.getString("Name","No name")+" Address "+ sharedPreferences.getString("Address","No Address"));
            }
        });
        save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(name.getText().toString().isEmpty() && address.getText().toString().isEmpty()){
                    Toast.makeText(MainActivity.this,"Plz Enter all the data",Toast.LENGTH_LONG).show();
                }else{
                    String nameData=name.getText().toString().trim();
                    String addressData=address.getText().toString().trim();
                    SharedPreferences.Editor editor=sharedPreferences.edit();
                    editor.putString("Name",nameData);
                    editor.putString("Address",addressData);
                    editor.apply();
                }
            }
        });
    }
}

코드를 보면 Save 버튼 클릭 시 edit()으로 Editor 객체를 얻은 뒤 putString()으로 값을 담고, 마지막에 editor.apply()를 호출해 변경 사항을 비동기적으로 저장합니다. 두 입력 필드가 모두 비어 있으면 토스트 메시지로 사용자에게 알려주도록 처리했습니다.

4단계 – manifest.xml은 별도로 수정할 필요가 없습니다. 이제 앱을 실행해 보겠습니다. 실제 Android 기기를 컴퓨터에 연결한 상태에서 Android Studio 툴바의 Run 아이콘을 클릭하고, 실행 대상으로 자신의 모바일 기기를 선택합니다. 그러면 아래와 같은 기본 화면이 표시됩니다.

안드로이드 SharedPreferences에서 apply() 사용법 – 예제와 함께 배우기

위 화면에서 이름과 주소를 입력한 뒤 Save 버튼을 클릭했습니다.

안드로이드 SharedPreferences에서 apply() 사용법 – 예제와 함께 배우기

그다음 read 버튼을 클릭하면, 저장되어 있던 이름과 주소 값이 TextView에 추가되어 표시됩니다. 이처럼 apply()를 활용하면 UI 스레드를 막지 않으면서 데이터를 빠르고 안전하게 저장할 수 있습니다.