공유 환경 설정에서 클래스 객체 저장 및 검색


111

Android에서 클래스의 객체를 공유 환경 설정에 저장하고 나중에 객체를 검색 할 수 있습니까?

가능하다면 어떻게해야합니까? 가능하지 않다면 다른 가능성은 무엇입니까?

직렬화가 하나의 옵션이라는 것을 알고 있지만 공유 기본 설정을 사용하여 가능성을 찾고 있습니다.


나는 케이스의 사람이 필요 그것에 헬퍼 라이브러리를 추가 : github.com/ionull/objectify
TSUNG 고 씨


여기입니다 대답 비슷한 질문에이.
tpk


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

답변:


15

불가능합니다.

SharedPrefences SharePreferences.Editor 에는 단순 값만 저장할 수 있습니다.

특히 저장해야 할 수업은 무엇입니까?


1
감사합니다. 클래스의 일부 데이터 멤버를 저장하고 싶습니다. 공유 환경 설정을 사용하여 데이터 멤버의 각 값을 저장하고 싶지 않습니다. 객체로 저장하고 싶습니다. 공유 환경 설정이 아닌 경우 다른 옵션은 무엇입니까?
androidGuy 2011 년

5
직렬화하여 데이터베이스 (SQLite) / 플랫 파일에 저장합니다.
Blundell 2011 년

5
대답은 완전하지 않습니다. 가능한 해결책은 pojo를 ByteArrayOutPutStream으로 변환하고 SharedPreferences에 String으로 저장하는 것입니다
rallat

27
다른 옵션은 json으로 저장 한 다음 다시 매핑합니다. GSON 또는 잭슨 정말 간단합니다
rallat

2
나를 밖으로 내 타임머신 2011 뒤로 그림하자
Blundell은

324

예, 다음을 사용하여 수행 할 수 있습니다. Gson을

GitHub 에서 작업 코드 다운로드

SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);

저장을 위해

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

얻기 위해

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

업데이트 1

최신 버전의 GSON은 github.com/google/gson 에서 다운로드 할 수 있습니다. .

업데이트 2

Gradle / Android Studio를 사용하는 경우 build.gradle종속성 섹션 에 다음을 입력 하십시오.

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

내 경우에는 작동하지 않습니다. jar를 libs에 넣고 빌드 경로에 설정 한 후에도 Gson 클래스가 해결되지 않습니다.
Shirish Herwade 2013 년

깨끗한 프로젝트 후 @ShirishHerwade 시도
Parag Chauhan

@parag도 작동하지 않습니다. 위의 오류를 제거하기 위해 해당 항아리를 사용하는 단계를 알려주시겠습니까? 나는 성공적 libs와 항아리 폴더 다음도 내 바탕 화면에 외부 저장 JSON을 추가하려고 "자바 빌드 경로"에 있다고 덧붙였다 때문에
Shirish Herwade

7
이 대답은 제한 사항도 언급하면 ​​더 좋을 것입니다. 이런 방식으로 어떤 종류의 객체를 저장하고 검색 할 수 있습니까? 분명히 모든 수업에서 작동하지는 않습니다.
wvdz 2014-06-22

3
String json = gson.toJson("MyObject");문자열이 아닌 객체 여야합니다.
Ahmed Hegazy

44

Outputstream을 사용하여 Object를 내부 메모리로 출력 할 수 있습니다. 그리고 문자열로 변환 한 다음 기본 설정에 저장합니다. 예를 들면 :

    mPrefs = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor ed = mPrefs.edit();
    ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();

    ObjectOutputStream objectOutput;
    try {
        objectOutput = new ObjectOutputStream(arrayOutputStream);
        objectOutput.writeObject(object);
        byte[] data = arrayOutputStream.toByteArray();
        objectOutput.close();
        arrayOutputStream.close();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Base64OutputStream b64 = new Base64OutputStream(out, Base64.DEFAULT);
        b64.write(data);
        b64.close();
        out.close();

        ed.putString(key, new String(out.toByteArray()));

        ed.commit();
    } catch (IOException e) {
        e.printStackTrace();
    }

Preference에서 Object를 추출해야 할 때. 아래와 같이 코드를 사용하십시오.

    byte[] bytes = mPrefs.getString(indexName, "{}").getBytes();
    if (bytes.length == 0) {
        return null;
    }
    ByteArrayInputStream byteArray = new ByteArrayInputStream(bytes);
    Base64InputStream base64InputStream = new Base64InputStream(byteArray, Base64.DEFAULT);
    ObjectInputStream in;
    in = new ObjectInputStream(base64InputStream);
    MyObject myObject = (MyObject) in.readObject();

안녕하세요, 이것이 얼마 전에 게시 된 것을 알고 있지만 저장된 객체를 추출하기위한 코드가 정확하다고 확신하십니까? 단순히 "new ObjectInputStream (byteArray)"를 갖는 대신 명시 적 생성자를 정의해야하는 방법에 대해 징징 거리는 마지막 두 줄에서 여러 오류가 발생합니다. 도와 주셔서 감사합니다!
Wakka Wakka Wakka 2013 년

안녕하세요, 갑자기 EOFException이 발생합니다. in = new ObjectInputStream (base64InputStream); 나는 당신이하는 것과 똑같은 방식으로 공유 환경에 그것을 쓰고 있습니다. 무엇이 잘못 될 수 있다고 생각하십니까?
marienke

Object를 pref에 쓸 때 예외가 있습니까? SDK에서 : 프로그램이 입력 작업 중에 파일 또는 스트림의 끝을 만나면 EOFException이 발생합니다.
Kislingk

좋아요, 이것은 지금 까지이 문제에 대해 내가 만난 최고의 솔루션입니다. 종속성이 없습니다. 그러나 객체에 대해 ObjectOutput / InputStream을 사용할 수 있으려면 해당 객체와 그 안에있는 모든 사용자 정의 객체가 Serializable 인터페이스를 구현해야합니다.
user1112789

8

나는 같은 문제가 있었고 여기 내 해결책이 있습니다.

공유 기본 설정에 저장하려는 MyClass 및 ArrayList <MyClass> 클래스가 있습니다. 처음에는 JSON 객체로 변환하는 메서드를 MyClass에 추가했습니다.

public JSONObject getJSONObject() {
    JSONObject obj = new JSONObject();
    try {
        obj.put("id", this.id);
        obj.put("name", this.name);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return obj;
}

다음은 "ArrayList <MyClass> items"개체를 저장하는 방법입니다.

SharedPreferences mPrefs = context.getSharedPreferences("some_name", 0);
    SharedPreferences.Editor editor = mPrefs.edit();

    Set<String> set= new HashSet<String>();
    for (int i = 0; i < items.size(); i++) {
        set.add(items.get(i).getJSONObject().toString());
    }

    editor.putStringSet("some_name", set);
    editor.commit();

객체를 검색하는 방법은 다음과 같습니다.

public static ArrayList<MyClass> loadFromStorage() {
    SharedPreferences mPrefs = context.getSharedPreferences("some_name", 0);

    ArrayList<MyClass> items = new ArrayList<MyClass>();

    Set<String> set = mPrefs.getStringSet("some_name", null);
    if (set != null) {
        for (String s : set) {
            try {
                JSONObject jsonObject = new JSONObject(s);
                Long id = jsonObject.getLong("id"));
                String name = jsonObject.getString("name");
                MyClass myclass = new MyClass(id, name);

                items.add(myclass);

            } catch (JSONException e) {
                e.printStackTrace();
         }
    }
    return items;
}

Shared Preferences의 StringSet은 API 11부터 사용할 수 있습니다.


내 문제를 해결했습니다. 뭔가 추가하고 싶어요. 처음 사용하려면 세트가 null인지 확인해야합니다. if (set! = null) {for (String s : set) {..}}
xevser

@xevser 제안대로 null 검사를 추가했습니다. 감사.
Micer

6

Gson 라이브러리 사용 :

dependencies {
compile 'com.google.code.gson:gson:2.8.2'
}

저장:

Gson gson = new Gson();
//Your json response object value store in json object
JSONObject jsonObject = response.getJSONObject();
//Convert json object to string
String json = gson.toJson(jsonObject);
//Store in the sharedpreference
getPrefs().setUserJson(json);

검색:

String json = getPrefs().getUserJson();

Parcel은 범용 직렬화 메커니즘이 아닙니다. 이 클래스 (및 임의의 개체를 Parcel에 배치하기위한 해당 Parcelable API)는 고성능 IPC 전송으로 설계되었습니다. 따라서 Parcel 데이터를 영구 저장소에 배치하는 것은 적절하지 않습니다. Parcel에있는 데이터의 기본 구현을 변경하면 오래된 데이터를 읽을 수 없게 될 수 있습니다.
Marcos Vasconcelos

1

PowerPreference라이브러리를 사용하여 3 단계로 쉽게 할 수 있습니다 !

https://github.com/AliAsadi/PowerPreference

1. 개체 만들기

Object obj = new Object();

2. 공유 기본 설정에 쓰기

PowerPreference.getDefaultFile().put("object",obj);

3. 개체 얻기

Object obj = PowerPreference.getDefaultFile()
                            .getObject("object", Object.class);

0

이 객체-> TinyDB--Android-Shared-Preferences-Turbo를 사용 하면 매우 간단합니다. 배열, 정수, 문자열 목록 등과 같이 일반적으로 사용되는 대부분의 객체를 저장할 수 있습니다.


쿨,하지만 난 (POJO이며)이 그냥 사용자 정의 개체에 대한 primitie 유형 (문자열, 더블, INT, 등) 작동 생각
CommonSenseCode

지금 읽어보기를 확인, 사용자 정의 개체에 대한 작동, 그것은 업데이트되었습니다
KC ochibili

0

당신이 사용할 수있는 펠리페 실베스트르에 의해 - 복잡한 환경 설정 안드로이드를 사용자 정의 개체를 저장하는 라이브러리입니다. 기본적으로 GSON 메커니즘을 사용하여 객체를 저장합니다.

개체를 환경 설정에 저장하려면 :

User user = new User();
user.setName("Felipe");
user.setAge(22); 
user.setActive(true); 

ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(
     this, "mypref", MODE_PRIVATE);
complexPreferences.putObject("user", user);
complexPreferences.commit();

다시 검색하려면 :

ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(this, "mypref", MODE_PRIVATE);
User user = complexPreferences.getObject("user", User.class);

Parcel은 범용 직렬화 메커니즘이 아닙니다. 이 클래스 (및 임의의 개체를 Parcel에 배치하기위한 해당 Parcelable API)는 고성능 IPC 전송으로 설계되었습니다. 따라서 Parcel 데이터를 영구 저장소에 배치하는 것은 적절하지 않습니다. Parcel에있는 데이터의 기본 구현을 변경하면 오래된 데이터를 읽을 수 없게 될 수 있습니다.
Marcos Vasconcelos

더 이상 사용되지 않습니다
IgorGanapolsky

0

Gradle Build.gradle을 사용하여 GSON을 사용할 수 있습니다.

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

그런 다음 코드에서, 예를 들어 Kotlin과 문자열 / 부울 쌍이 있습니다.

        val nestedData = HashMap<String,Boolean>()
        for (i in 0..29) {
            nestedData.put(i.toString(), true)
        }
        val gson = Gson()
        val jsonFromMap = gson.toJson(nestedData)

SharedPrefs에 추가 :

        val sharedPrefEditor = context.getSharedPreferences(_prefName, Context.MODE_PRIVATE).edit()
        sharedPrefEditor.putString("sig_types", jsonFromMap)
        sharedPrefEditor.apply()

이제 데이터를 검색합니다.

val gson = Gson()
val sharedPref: SharedPreferences = context.getSharedPreferences(_prefName, Context.MODE_PRIVATE)
val json = sharedPref.getString("sig_types", "false")
val type = object : TypeToken<Map<String, Boolean>>() {}.type
val map = gson.fromJson(json, type) as LinkedTreeMap<String,Boolean>
for (key in map.keys) {
     Log.i("myvalues", key.toString() + map.get(key).toString())
}

Parcel은 범용 직렬화 메커니즘이 아닙니다. 이 클래스 (및 임의의 개체를 Parcel에 배치하기위한 해당 Parcelable API)는 고성능 IPC 전송으로 설계되었습니다. 따라서 Parcel 데이터를 영구 저장소에 배치하는 것은 적절하지 않습니다. Parcel에있는 데이터의 기본 구현을 변경하면 오래된 데이터를 읽을 수 없게 될 수 있습니다.
Marcos Vasconcelos

0

CURD (Common Shared Preferences) SharedPreference : 간단한 Kotlin 클래스를 사용하여 값-키 쌍 형식으로 데이터를 저장합니다.

var sp = SharedPreference(this);

데이터 저장 :

String, Int 및 Boolean 데이터를 저장하기 위해 이름이 같고 매개 변수가 다른 세 가지 메서드가 있습니다 (메소드 오버로딩).

save("key-name1","string value")
save("key-name2",int value)
save("key-name3",boolean)

데이터 검색 : SharedPreferences에 저장된 데이터를 검색하려면 다음 방법을 사용하십시오.

sp.getValueString("user_name")
sp.getValueInt("user_id")
sp.getValueBoolean("user_session",true)

모든 데이터 지우기 : 전체 SharedPreferences를 지우려면 아래 코드를 사용하십시오.

 sp.clearSharedPreference()

특정 데이터 제거 :

sp.removeValue("user_name")

공통 공유 선호 클래스

import android.content.Context
import android.content.SharedPreferences

class SharedPreference(private val context: Context) {
    private val PREFS_NAME = "coredata"
    private val sharedPref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
    //********************************************************************************************** save all
    //To Store String data
    fun save(KEY_NAME: String, text: String) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putString(KEY_NAME, text)
        editor.apply()
    }
    //..............................................................................................
    //To Store Int data
    fun save(KEY_NAME: String, value: Int) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putInt(KEY_NAME, value)
        editor.apply()
    }
    //..............................................................................................
    //To Store Boolean data
    fun save(KEY_NAME: String, status: Boolean) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putBoolean(KEY_NAME, status)
        editor.apply()
    }
    //********************************************************************************************** retrieve selected
    //To Retrieve String
    fun getValueString(KEY_NAME: String): String? {

        return sharedPref.getString(KEY_NAME, "")
    }
    //..............................................................................................
    //To Retrieve Int
    fun getValueInt(KEY_NAME: String): Int {

        return sharedPref.getInt(KEY_NAME, 0)
    }
    //..............................................................................................
    // To Retrieve Boolean
    fun getValueBoolean(KEY_NAME: String, defaultValue: Boolean): Boolean {

        return sharedPref.getBoolean(KEY_NAME, defaultValue)
    }
    //********************************************************************************************** delete all
    // To clear all data
    fun clearSharedPreference() {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.clear()
        editor.apply()
    }
    //********************************************************************************************** delete selected
    // To remove a specific data
    fun removeValue(KEY_NAME: String) {
        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.remove(KEY_NAME)
        editor.apply()
    }
}

블로그 : https://androidkeynotes.blogspot.com/2020/02/shared-preference.html


-2

SharedPreferences에 객체를 저장할 수있는 방법이 없습니다. 내가 한 일은 공용 클래스를 만들고 필요한 모든 매개 변수를 넣고 setter와 getter를 만드는 것입니다. 객체에 액세스 할 수있었습니다.


-3

응용 프로그램이 종료 된 후에도 또는 실행중인 동안에도 개체를 검색해야합니까?

데이터베이스에 저장할 수 있습니다.
또는 단순히 사용자 정의 애플리케이션 클래스를 생성하십시오.

public class MyApplication extends Application {

    private static Object mMyObject;
    // static getter & setter
    ...
}

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application ... android:name=".MyApplication">
        <activity ... />
        ...
    </application>
    ...
</manifest>

그리고 모든 활동에서 다음을 수행합니다.

((MyApplication) getApplication).getMyObject();

정말 최선의 방법은 아니지만 작동합니다.


-6

예. Sharedpreference를 사용하여 객체를 저장하고 검색 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.