Android SharedPreferences가 객체를 저장 / 저장하는 방법


216

많은 필드를 포함하는 많은 장소에서 사용자 객체를 가져와야합니다. 로그인 후 이러한 사용자 개체를 저장 / 저장하고 싶습니다. 이런 종류의 시나리오를 어떻게 구현할 수 있습니까?

나는 이것을 다음과 같이 저장할 수 없다 :

SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefsEditor.putString("BusinessUnit", strBusinessUnit);

어떤 유형의 데이터를 저장 하시겠습니까?
ilango j


~ " 및 Executive Object " 는 무슨 뜻 입니까? StackOverflow에 게시하기 전에 문법을 확인하십시오.
IgorGanapolsky 2016 년

많은 기능을 가진이 라이브러리를 사용할 수 있습니다 ... github.com/moinkhan-in/PreferenceSpider
Moinkhan

답변:


548

gson.jar을 사용하여 클래스 객체를 SharedPreferences 에 저장할 수 있습니다 . 이 항아리는 google-gson 에서 다운로드 할 수 있습니다

또는 Gradle 파일에 GSON 종속성을 추가하십시오.

implementation 'com.google.code.gson:gson:2.8.5'

공유 환경 설정 작성 :

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);

저장하려면 :

MyObject myObject = new MyObject;
//set variables of 'myObject', etc.

Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(myObject);
prefsEditor.putString("MyObject", json);
prefsEditor.commit();

검색하려면

Gson gson = new Gson();
String json = mPrefs.getString("MyObject", "");
MyObject obj = gson.fromJson(json, MyObject.class);

9
덕분에 친구! 그러나 저장 부분 (행 3)에서 올바르지 않은 올바른 코드는 다음과 같습니다. String json = gson.toJson (myObject);
cesarferreira

항아리 3 개가 모두 필요합니까? 그 링크에는 3 개가 있습니다. . .
coolcool1994

3
단지 다운로드를위한 올바른 URL은 다음과 같습니다 search.maven.org/...
Shajeel 아프

2
이것은 더 여기있는 StackOverflowException의 xD 읽기에 리드가 있음을 순환 참조에 문제가 stackoverflow.com/questions/10209959/...
phuwin

1
@rozina 예 Gson이 더 좋습니다. 우선 직렬화를 사용하려면 오브젝트와 오브젝트 안의 모든 오브젝트가 직렬화 인터페이스를 구현해야합니다. gson에는 필요하지 않습니다. gson은 객체가 객체 목록 일 때도 효과적입니다.
Neville Nazerane

36

@MuhammadAamirALi의 답변에 추가하기 위해 Gson을 사용하여 객체 목록을 저장하고 검색 할 수 있습니다

사용자 정의 개체 목록을 SharedPreferences에 저장

public static final String KEY_CONNECTIONS = "KEY_CONNECTIONS";
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();

User entity = new User();
// ... set entity fields

List<Connection> connections = entity.getConnections();
// convert java object to JSON format,
// and returned as JSON formatted string
String connectionsJSONString = new Gson().toJson(connections);
editor.putString(KEY_CONNECTIONS, connectionsJSONString);
editor.commit();

SharedPreferences에서 사용자 정의 개체 목록 가져 오기

String connectionsJSONString = getPreferences(MODE_PRIVATE).getString(KEY_CONNECTIONS, null);
Type type = new TypeToken < List < Connection >> () {}.getType();
List < Connection > connections = new Gson().fromJson(connectionsJSONString, type);

3
"유형"이란 무엇입니까? (Get리스트, 2 행).
gangadhars

15

이 스레드가 약간 낡았다는 것을 알고 있습니다. 그러나 나는 누군가에게 도움이되기를 희망하면서 이것을 게시 할 것입니다. 객체를 문자열 로 직렬화 하여 모든 객체의 필드 를 공유 환경 설정 저장할 수 있습니다 . 여기서는 GSON객체를 공유 환경 설정에 저장하는 데 사용 했습니다.

환경 설정에 객체 저장 :

public static void saveObjectToSharedPreference(Context context, String preferenceFileName, String serializedObjectKey, Object object) {
    SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceFileName, 0);
    SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit();
    final Gson gson = new Gson();
    String serializedObject = gson.toJson(object);
    sharedPreferencesEditor.putString(serializedObjectKey, serializedObject);
    sharedPreferencesEditor.apply();
}

환경 설정에서 객체 검색 :

public static <GenericClass> GenericClass getSavedObjectFromPreference(Context context, String preferenceFileName, String preferenceKey, Class<GenericClass> classType) {
    SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceFileName, 0);
    if (sharedPreferences.contains(preferenceKey)) {
        final Gson gson = new Gson();
        return gson.fromJson(sharedPreferences.getString(preferenceKey, ""), classType);
    }
    return null;
}

노트 :

gradle 에 추가 compile 'com.google.code.gson:gson:2.6.2'해야 dependencies합니다.

:

//assume SampleClass exists
SampleClass mObject = new SampleObject();

//to store an object
saveObjectToSharedPreference(context, "mPreference", "mObjectKey", mObject);

//to retrive object stored in preference
mObject = getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class);

최신 정보:

@Sharp_Edge가 주석에서 지적했듯이 위의 솔루션은 작동하지 않습니다. List .

의 서명에 대한 약간의 수정 getSavedObjectFromPreference()-에서 Class<GenericClass> classType로는 Type classType일반화 된이 솔루션을 만들 것입니다. 수정 된 기능 서명

public static <GenericClass> GenericClass getSavedObjectFromPreference(Context context, String preferenceFileName, String preferenceKey, Type classType)

호출하기 위해

getSavedObjectFromPreference(context, "mPreference", "mObjectKey", (Type) SampleClass.class)

행복한 코딩!


1
이것은 정말 도움이되었습니다 감사합니다. 여기에 의견을 말해야하는 사람은 onSaveInstanceState에서 saveObjectToSharedPreference를 호출해야합니까? 이제 onSaveInstanceState에 있지만 10 초마다 실시간 데이터를 수집하는 응용 프로그램에서 가끔씩 딸꾹질이 발생하고 saveObjectToSharedPreference로 저장하는 객체에서 일부 판독 값이 손실됩니다. 모든 생각을 환영합니다.
Frank Zappa

안녕하세요 @FrankZappa, 문제를 완전히 이해하지 못했지만 여기에 가십시오 . commit대신 사용하십시오 apply. 도움이 될 수 있습니다.
tpk 2018

감사. 설명하려고 노력하겠습니다. 내 Android 앱은 약 10 초마다 실시간으로 데이터를 수집합니다. 이 데이터 수집은 객체가 아니라 전역 변수와 논리 만 사용합니다. 그런 다음 데이터가 요약되어 Java 객체에 저장됩니다. a) 내 지식으로 onSavedInstanceState에 객체를 저장할 수 없으며 b) 화면이 회전하면 객체가 파괴되고 다시 만들어지기 때문에 위의 방법을 사용하여 SharedPreferences를 통해 Java 객체를 저장하고 검색합니다. 따라서 SharedPrefs 접근 방식을 사용하므로 화면이 회전 할 때 객체가 값을 잃지 않습니다. (계속)
프랭크 자파

saveObjectToSharedPreferences 루틴을 onSaveInstanceState에 배치했습니다. getSavedObjectFromPreference 루틴을 onRestoreInstanceState에 배치했습니다. 그러나 화면 회전으로 인해 누락 된 객체 업데이트 세트를 테스트했지만 여전히 얻었습니다. 따라서 saveObjectToSharedPreferences 호출을 실제 논리에 더 가깝게 이동해야합니까? 마지막으로 커밋 및 적용하는 방법은 무엇입니까?
Frank Zappa

1
@ 2943 솔루션이 훌륭해 보이지만 예를 들어 목록이 있으면 List<CustomClass>어떻게해야합니까? getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class)허용하지 않습니다 List<CustomClass>.class:(
Sharp Edge

6

Constants키 또는 변수를 저장하여 데이터를 가져 오거나 저장 하는 전역 클래스 를 만드는 것이 좋습니다.

데이터를 저장하려면이 메소드를 호출하여 모든 위치에서 데이터를 저장하십시오.

public static void saveData(Context con, String variable, String data)
{
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(con);
    prefs.edit().putString(variable, data).commit();
}

데이터를 얻는 데 사용하십시오.

public static String getData(Context con, String variable, String defaultValue)
{
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(con);
    String data = prefs.getString(variable, defaultValue);
    return data;
}

이와 같은 방법으로 트릭을 수행 할 수 있습니다.

public static User getUserInfo(Context con)
{
    String id =  getData(con, Constants.USER_ID, null);
    String name =  getData(con, Constants.USER_NAME, null);
    if(id != null && name != null)
    {
            User user = new User(); //Hope you will have a user Object.
            user.setId(id);
            user.setName(name);
            //Here set other credentials.
            return user;
    }
    else
    return null;
}

데이터를 다시 가져 오려면 'variable'및 'defaultValue'로 무엇을 전달해야합니까?
Alex

상수 클래스를 만들지 마십시오. 코드가 동시에 결합되고 흩어져 있습니다.
Miha_x64

5

이 최선의 방법을 시도하십시오 :

PreferenceConnector.java

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class PreferenceConnector {
    public static final String PREF_NAME = "ENUMERATOR_PREFERENCES";
    public static final String PREF_NAME_REMEMBER = "ENUMERATOR_REMEMBER";
    public static final int MODE = Context.MODE_PRIVATE;


    public static final String name = "name";


    public static void writeBoolean(Context context, String key, boolean value) {
        getEditor(context).putBoolean(key, value).commit();
    }

    public static boolean readBoolean(Context context, String key,
            boolean defValue) {
        return getPreferences(context).getBoolean(key, defValue);
    }

    public static void writeInteger(Context context, String key, int value) {
        getEditor(context).putInt(key, value).commit();

    }

    public static int readInteger(Context context, String key, int defValue) {
        return getPreferences(context).getInt(key, defValue);
    }

    public static void writeString(Context context, String key, String value) {
        getEditor(context).putString(key, value).commit();

    }

    public static String readString(Context context, String key, String defValue) {
        return getPreferences(context).getString(key, defValue);
    }

    public static void writeLong(Context context, String key, long value) {
        getEditor(context).putLong(key, value).commit();
    }

    public static long readLong(Context context, String key, long defValue) {
        return getPreferences(context).getLong(key, defValue);
    }

    public static SharedPreferences getPreferences(Context context) {
        return context.getSharedPreferences(PREF_NAME, MODE);
    }

    public static Editor getEditor(Context context) {
        return getPreferences(context).edit();
    }

}

가치를 쓰십시오 :

PreferenceConnector.writeString(this, PreferenceConnector.name,"Girish");

그리고 다음을 사용하여 가치를 얻으십시오.

String name= PreferenceConnector.readString(this, PreferenceConnector.name, "");

2
이것은 Android의 SharedPreferences에 객체를 저장하는 것과 어떤 관련이 있습니까?
IgorGanapolsky 2016 년

Sharedpreferences 작업에 대한 자세한 내용은 stackoverflow.com/a/2614771/1815624 에서 확인할 수 있습니다. return PreferenceManager.getDefaultSharedPreferences(context);대신 return context.getSharedPreferences(PREF_NAME, MODE);
CranellWS가

3

prefsEditor이 후에 객체로 무엇을했는지 언급하지 않았지만 환경 설정 데이터를 유지하려면 다음을 사용해야합니다.

prefsEditor.commit();

2

여기에 도움이 될 수 있습니다.

public static boolean setObject(Context context, Object o) {
        Field[] fields = o.getClass().getFields();
        SharedPreferences sp = context.getSharedPreferences(o.getClass()
                .getName(), Context.MODE_PRIVATE);
        Editor editor = sp.edit();
        for (int i = 0; i < fields.length; i++) {
            Class<?> type = fields[i].getType();
            if (isSingle(type)) {
                try {
                    final String name = fields[i].getName();
                    if (type == Character.TYPE || type.equals(String.class)) {
                        Object value = fields[i].get(o);
                        if (null != value)
                            editor.putString(name, value.toString());
                    } else if (type.equals(int.class)
                            || type.equals(Short.class))
                        editor.putInt(name, fields[i].getInt(o));
                    else if (type.equals(double.class))
                        editor.putFloat(name, (float) fields[i].getDouble(o));
                    else if (type.equals(float.class))
                        editor.putFloat(name, fields[i].getFloat(o));
                    else if (type.equals(long.class))
                        editor.putLong(name, fields[i].getLong(o));
                    else if (type.equals(Boolean.class))
                        editor.putBoolean(name, fields[i].getBoolean(o));

                } catch (IllegalAccessException e) {
                    LogUtils.e(TAG, e);
                } catch (IllegalArgumentException e) {
                    LogUtils.e(TAG, e);
                }
            } else {
                // FIXME 是对象则不写入
            }
        }

        return editor.commit();
    }

https://github.com/AltasT/PreferenceVObjectFile/blob/master/PreferenceVObjectFile/src/com/altas/lib/PreferenceUtils.java


2
현재 "단지 코드"를 나타내므로 코드를 조금 더 설명해 주시겠습니까?
베르너

1

Json 형식을 사용하지 않고 안드로이드 공유 환경 설정에서 객체를 저장하고 복원하는 다른 방법

private static ExampleObject getObject(Context c,String db_name){
            SharedPreferences sharedPreferences = c.getSharedPreferences(db_name, Context.MODE_PRIVATE);
            ExampleObject o = new ExampleObject();
            Field[] fields = o.getClass().getFields();
            try {
                for (Field field : fields) {
                    Class<?> type = field.getType();
                    try {
                        final String name = field.getName();
                        if (type == Character.TYPE || type.equals(String.class)) {
                            field.set(o,sharedPreferences.getString(name, ""));
                        } else if (type.equals(int.class) || type.equals(Short.class))
                            field.setInt(o,sharedPreferences.getInt(name, 0));
                        else if (type.equals(double.class))
                            field.setDouble(o,sharedPreferences.getFloat(name, 0));
                        else if (type.equals(float.class))
                            field.setFloat(o,sharedPreferences.getFloat(name, 0));
                        else if (type.equals(long.class))
                            field.setLong(o,sharedPreferences.getLong(name, 0));
                        else if (type.equals(Boolean.class))
                            field.setBoolean(o,sharedPreferences.getBoolean(name, false));
                        else if (type.equals(UUID.class))
                            field.set(
                                    o,
                                    UUID.fromString(
                                            sharedPreferences.getString(
                                                    name,
                                                    UUID.nameUUIDFromBytes("".getBytes()).toString()
                                            )
                                    )
                            );

                    } catch (IllegalAccessException e) {
                        Log.e(StaticConfig.app_name, "IllegalAccessException", e);
                    } catch (IllegalArgumentException e) {
                        Log.e(StaticConfig.app_name, "IllegalArgumentException", e);
                    }
                }
            } catch (Exception e) {
                System.out.println("Exception: " + e);
            }
            return o;
        }
        private static void setObject(Context context, Object o, String db_name) {
            Field[] fields = o.getClass().getFields();
            SharedPreferences sp = context.getSharedPreferences(db_name, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            for (Field field : fields) {
                Class<?> type = field.getType();
                try {
                    final String name = field.getName();
                    if (type == Character.TYPE || type.equals(String.class)) {
                        Object value = field.get(o);
                        if (value != null)
                            editor.putString(name, value.toString());
                    } else if (type.equals(int.class) || type.equals(Short.class))
                        editor.putInt(name, field.getInt(o));
                    else if (type.equals(double.class))
                        editor.putFloat(name, (float) field.getDouble(o));
                    else if (type.equals(float.class))
                        editor.putFloat(name, field.getFloat(o));
                    else if (type.equals(long.class))
                        editor.putLong(name, field.getLong(o));
                    else if (type.equals(Boolean.class))
                        editor.putBoolean(name, field.getBoolean(o));
                    else if (type.equals(UUID.class))
                        editor.putString(name, field.get(o).toString());

                } catch (IllegalAccessException e) {
                    Log.e(StaticConfig.app_name, "IllegalAccessException", e);
                } catch (IllegalArgumentException e) {
                    Log.e(StaticConfig.app_name, "IllegalArgumentException", e);
                }
            }

            editor.apply();
        }

1

라이브러리를 사용하지 않고 환경 설정에 객체를 저장할 수 있습니다. 먼저 모든 객체 클래스가 Serializable을 구현해야합니다.

public class callModel implements Serializable {

private long pointTime;
private boolean callisConnected;

public callModel(boolean callisConnected,  long pointTime) {
    this.callisConnected = callisConnected;
    this.pointTime = pointTime;
}
public boolean isCallisConnected() {
    return callisConnected;
}
public long getPointTime() {
    return pointTime;
}

}

그런 다음이 두 가지 방법을 사용하여 객체를 문자열로, 문자열을 객체로 변환 할 수 있습니다.

 public static <T extends Serializable> T stringToObjectS(String string) {
    byte[] bytes = Base64.decode(string, 0);
    T object = null;
    try {
        ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
        object = (T) objectInputStream.readObject();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return object;
}

 public static String objectToString(Parcelable object) {
    String encoded = null;
    try {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        objectOutputStream.close();
        encoded = new String(Base64.encodeToString(byteArrayOutputStream.toByteArray(), 0));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return encoded;
}

저장하려면 :

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);
Editor prefsEditor = mPrefs.edit();
prefsEditor.putString("MyObject", objectToString(callModelObject));
prefsEditor.commit();

읽다

String value= mPrefs.getString("MyObject", "");
MyObject obj = stringToObjectS(value);

이러한 바이트를 별도의 파일에 쓰면 Base64 인코딩 및 XML 이스케이프를 피할 수 있습니다.
Miha_x64

1

1 단계 : 이 두 함수를 Java 파일에 붙여 넣습니다.

 public void setDefaults(String key, String value, Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString(key, value);
        editor.commit();
    }


    public static String getDefaults(String key, Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(key, null);
    }

2 단계 : 사용 저장 :

 setDefaults("key","value",this);

사용을 검색하려면 :

String retrieve= getDefaults("key",this);

다음과 같은 다른 키 이름을 사용하여 다른 공유 환경 설정을 지정할 수 있습니다.

setDefaults("key1","xyz",this);

setDefaults("key2","abc",this);

setDefaults("key3","pqr",this);

1

응답으로 얻은 전체 객체를 저장하려면 다음과 같은 작업을 수행하여 달성 할 수 있습니다.

먼저 아래와 같이 JSON을 util 클래스의 문자열로 변환하는 메소드를 작성하십시오.

 public static <T> T fromJson(String jsonString, Class<T> theClass) {
    return new Gson().fromJson(jsonString, theClass);
}

그런 다음 공유 환경 설정 클래스에서

 public void storeLoginResponse(yourResponseClass objName) {

    String loginJSON = UtilClass.toJson(customer);
    if (!TextUtils.isEmpty(customerJSON)) {
        editor.putString(AppConst.PREF_CUSTOMER, customerJSON);
        editor.commit();
    }
}

그런 다음 getPreferences에 대한 메소드를 작성하십시오.

public Customer getCustomerDetails() {
    String customerDetail = pref.getString(AppConst.PREF_CUSTOMER, null);
    if (!TextUtils.isEmpty(customerDetail)) {
        return GSONConverter.fromJson(customerDetail, Customer.class);
    } else {
        return new Customer();
    }
}

그런 다음 응답을 얻을 때 First 메소드를 호출하고 다음과 같은 공유 환경 설정에서 데이터를 가져와야 할 경우 Second 메소드를 호출하십시오.

String token = SharedPrefHelper.get().getCustomerDetails().getAccessToken();

그게 다야.

그것이 도움이되기를 바랍니다.

Happy Coding();


1

수락 된 답변을 사용하여 활동 전체에서 공유 환경 설정 데이터에 액세스하는 데 문제가있었습니다. 이 단계에서는 getSharedPreferences에 액세스 할 이름을 지정합니다.

Gradle Scripts 아래의 build.gradel (모듈 : app) 파일에 다음 종속성을 추가하십시오.

implementation 'com.google.code.gson:gson:2.8.5'

저장하려면 :

MyObject myObject = new MyObject;
//set variables of 'myObject', etc.

SharedPreferences mPrefs = getSharedPreferences("Name", Context.MODE_PRIVATE);

Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(myObject);
prefsEditor.putString("Key", json);
prefsEditor.commit();

다른 활동에서 검색하려면 다음을 수행하십시오.

SharedPreferences mPrefs = getSharedPreferences("Name", Context.MODE_PRIVATE);

Gson gson = new Gson();
String json = mPrefs.getString("Key", "");
MyObject obj = gson.fromJson(json, MyObject.class);

1
// SharedPrefHelper is a class contains the get and save sharedPrefernce data
public class SharedPrefHelper {

    // save data in sharedPrefences
    public static void setSharedOBJECT(Context context, String key, 
                                           Object value) {

        SharedPreferences sharedPreferences =  context.getSharedPreferences(
                context.getPackageName(), Context.MODE_PRIVATE);

        SharedPreferences.Editor prefsEditor = sharedPreferences.edit();
        Gson gson = new Gson();
        String json = gson.toJson(value);
        prefsEditor.putString(key, json);
        prefsEditor.apply();
    }

    // get data from sharedPrefences 
    public static Object getSharedOBJECT(Context context, String key) {

         SharedPreferences sharedPreferences = context.getSharedPreferences(
                           context.getPackageName(), Context.MODE_PRIVATE);

        Gson gson = new Gson();
        String json = sharedPreferences.getString(key, "");
        Object obj = gson.fromJson(json, Object.class);
        User objData = new Gson().fromJson(obj.toString(), User.class);
        return objData;
    }
}
// save data in your activity

User user = new User("Hussein","h@h.com","3107310890983");        
SharedPrefHelper.setSharedOBJECT(this,"your_key",user);        
User data = (User) SharedPrefHelper.getSharedOBJECT(this,"your_key");

Toast.makeText(this,data.getName()+"\n"+data.getEmail()+"\n"+data.getPhone(),Toast.LENGTH_LONG).show();
// User is the class you want to save its objects

public class User {

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    private String name,email,phone;
    public User(String name,String email,String phone){
          this.name=name;
          this.email=email;
          this.phone=phone;
    }
}
// put this in gradle

compile 'com.google.code.gson:gson:2.7'

이것이 도움이되기를 바랍니다 :)


1

여기에서 가져온 Kotlin Delegated Properties 를 사용하는 방법에 대해 설명 합니다. , 그러나에 확대 / 점점 SharedPreference 속성을 설정하는 간단한 메커니즘 수 있습니다.

들면 String, Int, Long, Float또는 Boolean, 상기 기준 SharePreference 게터 (S) 및 설정 부 (S)를 사용한다. 그러나 다른 모든 데이터 클래스의 경우 GSON을 사용하여String 하여 세터에 대해 . 그런 다음 게터에 대해 데이터 객체로 역 직렬화합니다.

다른 솔루션과 마찬가지로 gradle 파일에서 GSON을 종속성으로 추가해야합니다.

implementation 'com.google.code.gson:gson:2.8.6'

다음은 SharedPreferences에 저장하고 저장할 수있는 간단한 데이터 클래스의 예입니다.

data class User(val first: String, val last: String)

속성 대리자를 구현하는 클래스는 다음과 같습니다.

object UserPreferenceProperty : PreferenceProperty<User>(
    key = "USER_OBJECT",
    defaultValue = User(first = "Jane", last = "Doe"),
    clazz = User::class.java)

object NullableUserPreferenceProperty : NullablePreferenceProperty<User?, User>(
    key = "NULLABLE_USER_OBJECT",
    defaultValue = null,
    clazz = User::class.java)

object FirstTimeUser : PreferenceProperty<Boolean>(
        key = "FIRST_TIME_USER",
        defaultValue = false,
        clazz = Boolean::class.java
)

sealed class PreferenceProperty<T : Any>(key: String,
                                         defaultValue: T,
                                         clazz: Class<T>) : NullablePreferenceProperty<T, T>(key, defaultValue, clazz)

@Suppress("UNCHECKED_CAST")
sealed class NullablePreferenceProperty<T : Any?, U : Any>(private val key: String,
                                                           private val defaultValue: T,
                                                           private val clazz: Class<U>) : ReadWriteProperty<Any, T> {

    override fun getValue(thisRef: Any, property: KProperty<*>): T = HandstandApplication.appContext().getPreferences()
            .run {
                when {
                    clazz.isAssignableFrom(String::class.java) -> getString(key, defaultValue as String?) as T
                    clazz.isAssignableFrom(Int::class.java) -> getInt(key, defaultValue as Int) as T
                    clazz.isAssignableFrom(Long::class.java) -> getLong(key, defaultValue as Long) as T
                    clazz.isAssignableFrom(Float::class.java) -> getFloat(key, defaultValue as Float) as T
                    clazz.isAssignableFrom(Boolean::class.java) -> getBoolean(key, defaultValue as Boolean) as T
                    else -> getObject(key, defaultValue, clazz)
                }
            }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: T) = HandstandApplication.appContext().getPreferences()
            .edit()
            .apply {
                when {
                    clazz.isAssignableFrom(String::class.java) -> putString(key, value as String?) as T
                    clazz.isAssignableFrom(Int::class.java) -> putInt(key, value as Int) as T
                    clazz.isAssignableFrom(Long::class.java) -> putLong(key, value as Long) as T
                    clazz.isAssignableFrom(Float::class.java) -> putFloat(key, value as Float) as T
                    clazz.isAssignableFrom(Boolean::class.java) -> putBoolean(key, value as Boolean) as T
                    else -> putObject(key, value)
                }
            }
            .apply()

    private fun Context.getPreferences(): SharedPreferences = getSharedPreferences(APP_PREF_NAME, Context.MODE_PRIVATE)

    private fun <T, U> SharedPreferences.getObject(key: String, defValue: T, clazz: Class<U>): T =
            Gson().fromJson(getString(key, null), clazz) as T ?: defValue

    private fun <T> SharedPreferences.Editor.putObject(key: String, value: T) = putString(key, Gson().toJson(value))

    companion object {
        private const val APP_PREF_NAME = "APP_PREF"
    }
}

참고 :의 내용을 업데이트 할 필요는 없습니다 sealed class. 위임 속성은 개체 / 싱글 톤이다 UserPreferenceProperty, NullableUserPreferenceProperty하고 FirstTimeUser.

SharedPreferences에서 저장 / 가져 오기위한 새 데이터 객체를 설정하려면 이제 네 줄을 추가하는 것이 쉽습니다.

object NewPreferenceProperty : PreferenceProperty<String>(
        key = "NEW_PROPERTY",
        defaultValue = "",
        clazz = String::class.java)

마지막으로 by키워드를 사용하여 SharedPreferences에 대한 값을 읽고 쓸 수 있습니다 .

private var user: User by UserPreferenceProperty
private var nullableUser: User? by NullableUserPreferenceProperty
private var isFirstTimeUser: Boolean by 

Log.d("TAG", user) // outputs the `defaultValue` for User the first time
user = User(first = "John", last = "Doe") // saves this User to the Shared Preferences
Log.d("TAG", user) // outputs the newly retrieved User (John Doe) from Shared Preferences

0

Object가 복잡하면 Serialize / XML / JSON을 직렬화하여 해당 내용을 SD 카드에 저장하는 것이 좋습니다. http://developer.android.com/guide/topics/data/data-storage.html#filesExternal 에서 외부 저장소에 저장하는 방법에 대한 추가 정보를 찾을 수 있습니다.


추가 권한이 필요하지 않습니까 (SD 카드)?
rishabh

예. SD 카드에 기록한 이후로 가능합니다.
trenpixster

1
내 경험상 사용자에게 필요한 권한이 적을수록 좋습니다. 위에서 언급 한 Gson을 사용하는 것이 실행 가능한 옵션이 아닌 경우 SD 카드를 선택해야합니다.
rishabh

그래, 나도 동의한다. JSON 결과가 충분히 큰 경우에만 SD 카드가 옵션이어야합니다. 내가 말한 절충입니다.
trenpixster

0

이 개 파일에 대한 귀하의 모든 문제가 해결된다 된 SharedPreferences

1) AppPersistence.java

    public class AppPersistence {
    public enum keys {
        USER_NAME, USER_ID, USER_NUMBER, USER_EMAIL, USER_ADDRESS, CITY, USER_IMAGE,
        DOB, MRG_Anniversary, COMPANY, USER_TYPE, support_phone
    }

    private static AppPersistence mAppPersistance;
    private SharedPreferences sharedPreferences;

    public static AppPersistence start(Context context) {
        if (mAppPersistance == null) {
            mAppPersistance = new AppPersistence(context);
        }
        return mAppPersistance;
    }

    private AppPersistence(Context context) {
        sharedPreferences = context.getSharedPreferences(context.getString(R.string.prefrence_file_name),
                Context.MODE_PRIVATE);
    }

    public Object get(Enum key) {
        Map<String, ?> all = sharedPreferences.getAll();
        return all.get(key.toString());
    }

    void save(Enum key, Object val) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        if (val instanceof Integer) {
            editor.putInt(key.toString(), (Integer) val);
        } else if (val instanceof String) {
            editor.putString(key.toString(), String.valueOf(val));
        } else if (val instanceof Float) {
            editor.putFloat(key.toString(), (Float) val);
        } else if (val instanceof Long) {
            editor.putLong(key.toString(), (Long) val);
        } else if (val instanceof Boolean) {
            editor.putBoolean(key.toString(), (Boolean) val);
        }
        editor.apply();
    }

    void remove(Enum key) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.remove(key.toString());
        editor.apply();
    }

    public void removeAll() {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.clear();
        editor.apply();
    }
}

2) AppPreference.java

public static void setPreference(Context context, Enum Name, String Value) {
        AppPersistence.start(context).save(Name, Value);
    }

    public static String getPreference(Context context, Enum Name) {
        return (String) AppPersistence.start(context).get(Name);
    }

    public static void removePreference(Context context, Enum Name) {
        AppPersistence.start(context).remove(Name);
    }
}

이제 저장, 제거 또는 좋아할 수 있습니다.

-저장

AppPreference.setPreference(context, AppPersistence.keys.USER_ID, userID);

-없애다

AppPreference.removePreference(context, AppPersistence.keys.USER_ID);

-가져 오기

 AppPreference.getPreference(context, AppPersistence.keys.USER_ID);

0

SharedPreference에 데이터 저장

SharedPreferences mprefs = getSharedPreferences(AppConstant.PREFS_NAME, MODE_PRIVATE)
mprefs.edit().putString(AppConstant.USER_ID, resUserID).apply();

0

저장 목록에 대한 utils 클래스 SharedPreferences

public class SharedPrefApi {
    private SharedPreferences sharedPreferences;
    private Gson gson;

    public SharedPrefApi(Context context, Gson gson) {
        this.sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        this.gson = gson;
    } 

    ...

    public <T> void putObject(String key, T value) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, gson.toJson(value));
        editor.apply();
    }

    public <T> T getObject(String key, Class<T> clazz) {
        return gson.fromJson(getString(key, null), clazz);
    }
}

사용

// for save
sharedPrefApi.putList(SharedPrefApi.Key.USER_LIST, userList);

// for retrieve
List<User> userList = sharedPrefApi.getList(SharedPrefApi.Key.USER_LIST, User.class);

.
내 유틸리티의 전체 코드 // 활동 코드의 예제를 사용하여 확인


0

jackson을 사용하여 객체를 저장했습니다 ( jackson ).

gradle에 jackson 라이브러리를 추가했습니다.

api 'com.fasterxml.jackson.core:jackson-core:2.9.4'
api 'com.fasterxml.jackson.core:jackson-annotations:2.9.4'
api 'com.fasterxml.jackson.core:jackson-databind:2.9.4'

내 테스트 수업 :

public class Car {
    private String color;
    private String type;
    // standard getters setters
}

자바 객체에서 JSON으로 :

ObjectMapper objectMapper = new ObjectMapper();
String carAsString = objectMapper.writeValueAsString(car);

공유 환경 설정에 저장하십시오.

preferences.edit().car().put(carAsString).apply();

공유 환경 설정에서 복원하십시오.

ObjectMapper objectMapper = new ObjectMapper();
Car car = objectMapper.readValue(preferences.car().get(), Car.class);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.