lưu trữ và truy xuất một đối tượng lớp trong sở thích chia sẻ


111

Trong Android, chúng ta có thể lưu trữ một đối tượng của một lớp trong sở thích chia sẻ và truy xuất đối tượng sau đó không?

Nếu có thể làm thế nào để làm điều đó? Nếu không thể, các khả năng khác của việc đó là gì?

Tôi biết rằng tuần tự hóa là một lựa chọn, nhưng tôi đang tìm kiếm các khả năng sử dụng tùy chọn chia sẻ.


Tôi thêm một thư viện helper trong trường hợp ai đó cần nó: github.com/ionull/objectify
Tsung Goh


Đây là một câu trả lời cho câu hỏi tương tự.
tpk


Bạn có thể sử dụng thư viện này có rất nhiều tính năng được tích hợp sẵn. github.com/moinkhan-in/PreferenceSpider
Moinkhan,

Câu trả lời:


15

Không thể.

Bạn chỉ có thể lưu trữ các giá trị đơn giản trong SharedPrefences SharePreferences.Editor

Điều gì đặc biệt về lớp bạn cần lưu?


1
Cảm ơn. Tôi muốn lưu trữ một số thành viên dữ liệu của lớp và tôi không muốn lưu trữ từng giá trị của các thành viên dữ liệu bằng cách sử dụng tùy chọn chia sẻ Tôi muốn lưu trữ nó dưới dạng một đối tượng.
androidGuy

5
Serialise nó và lưu trữ nó, trong cơ sở dữ liệu (SQLite) / trong một tệp phẳng.
Blundell

5
Câu trả lời là không đầy đủ. Các giải pháp khả thi là để chuyển đổi các POJO vào ByteArrayOutputStream và tiết kiệm như String trong các SharedPreferences
rallat

27
một tùy chọn khác được lưu nó dưới dạng json và sau đó ánh xạ lại nó. Với GSON hoặc Jackson thực sự dễ dàng
rallat

2
hãy để tôi có được thời gian của tôi máy trở lại năm 2011 và con số đó ra
Blundell

324

Có, chúng tôi có thể làm điều này bằng cách sử dụng Gson

Tải xuống mã làm việc từ GitHub

SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);

Để tiết kiệm

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

Quên

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

Cập nhật1

Bạn có thể tải xuống phiên bản GSON mới nhất từ github.com/google/gson .

Update2

Nếu bạn đang sử dụng Gradle / Android Studio, chỉ cần đưa phần sau vào build.gradlephần phụ thuộc -

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

không hoạt động trong trường hợp của tôi. Ngay cả sau khi đặt jar trong libs và thiết lập trong đường dẫn xây dựng, lớp Gson vẫn không được giải quyết.
Shirish Herwade

Dự án sạch sau đó thử @ShirishHerwade
Parag Chauhan

@parag mà cũng không hoạt động. Bạn có thể vui lòng cho tôi biết các bước để sử dụng jar đó để loại bỏ lỗi trên. Bởi vì tôi đã thêm thành công mà jar trong thư mục libs và sau đó trong "java xây dựng con đường" cũng cố gắng thêm bên ngoài lưu trữ json trên máy tính để bàn của tôi
Shirish Herwade

7
Câu trả lời này sẽ tốt hơn nếu nó cũng đề cập đến những hạn chế của nó. Loại đối tượng nào chúng ta có thể và không thể lưu trữ và truy xuất theo cách này? Rõ ràng là nó sẽ không hoạt động cho tất cả các lớp.
wvdz

3
String json = gson.toJson("MyObject");phải là đối tượng không phải là một chuỗi.
Ahmed Hegazy

44

chúng ta có thể sử dụng Outputstream để xuất Đối tượng của mình vào bộ nhớ trong. Và chuyển đổi thành chuỗi sau đó lưu theo sở thích. Ví dụ:

    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();
    }

khi chúng ta cần trích xuất Đối tượng từ Sở thích. Sử dụng mã như bên dưới

    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();

Xin chào, tôi biết điều này đã được đăng một thời gian trước, nhưng bạn có chắc chắn mã bạn có để giải nén đối tượng được lưu trữ là chính xác không? Tôi nhận được nhiều lỗi ở 2 dòng cuối cùng than vãn về cách các hàm tạo rõ ràng cần được xác định thay vì chỉ có "ObjectInputStream mới (byteArray)". Cảm ơn đã giúp đỡ!
Wakka Wakka Wakka

Xin chào, tôi đột nhiên nhận được một EOFException trên in = new ObjectInputStream (base64InputStream); Tôi đang viết nó lên các prefs được chia sẻ giống hệt như cách bạn đang làm. Bạn nghĩ điều gì có thể sai?
marienke

Bạn có ngoại lệ nào khi viết Object to pref không? Từ SDK: Ném EOFException khi chương trình gặp phần cuối của tệp hoặc luồng trong quá trình thao tác nhập.
Kislingk

Kudos, đây là giải pháp tốt nhất mà tôi đã tìm ra cho vấn đề này cho đến nay. Không có phụ thuộc. Tuy nhiên, cần lưu ý rằng để có thể sử dụng ObjectOutput / InputStream cho một đối tượng, đối tượng đã nói và tất cả các đối tượng tùy chỉnh bên trong nó phải triển khai giao diện Serializable.
user1112789

8

Tôi đã gặp vấn đề tương tự, đây là giải pháp của tôi:

Tôi có lớp MyClass và ArrayList <MyClass> mà tôi muốn lưu vào Sở thích dùng chung. Lúc đầu, tôi đã thêm một phương thức vào MyClass để chuyển đổi nó thành đối tượng JSON:

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;
}

Sau đó, đây là phương pháp để lưu đối tượng "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();

Và đây là phương pháp để lấy đối tượng:

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;
}

Lưu ý rằng StringSet trong Shared Preferences có sẵn kể từ API 11.


Đã giải quyết vấn đề của tôi. Tôi muốn thêm một cái gì đó. Để sử dụng lần đầu tiên, chúng ta phải kiểm tra xem tập hợp có rỗng không. if (! set = null) {for (String s: bộ) {..}}
xevser

@xevser Tôi đã thêm kiểm tra rỗng như được đề xuất. Cảm ơn.
Micer

6

Sử dụng Thư viện Gson:

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

Cửa hàng:

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);

Lấy lại:

String json = getPrefs().getUserJson();

Bưu kiện không phải là một cơ chế tuần tự hóa có mục đích chung. Lớp này (và API Parcelable tương ứng để đặt các đối tượng tùy ý vào một Parcel) được thiết kế như một phương thức truyền tải IPC hiệu suất cao. Do đó, không thích hợp để đặt bất kỳ dữ liệu Parcel nào vào bộ nhớ liên tục: những thay đổi trong việc triển khai cơ bản của bất kỳ dữ liệu nào trong Parcel có thể khiến dữ liệu cũ hơn không thể đọc được.
Marcos Vasconcelos

1

Bạn có thể làm điều đó bằng PowerPreferencethư viện trong 3 bước đơn giản!

https://github.com/AliAsadi/PowerPreference

1. Tạo đối tượng

Object obj = new Object();

2. Ghi vào sở thích chia sẻ

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

3. Bắt đối tượng

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

0

Sử dụng đối tượng này -> TinyDB - Android-Shared-Preferences-Turbo rất đơn giản. bạn có thể lưu hầu hết các đối tượng thường được sử dụng với nó như mảng, số nguyên, danh sách chuỗi, v.v.


Mát mẻ, nhưng tôi nghĩ rằng đây chỉ hoạt động với nhiều loại primitie (String, double, int, vv) không cho các đối tượng tùy chỉnh (POJO)
CommonSenseCode

nó hiện hoạt động cho các đối tượng tùy chỉnh, hãy kiểm tra ReadMe, nó đã được cập nhật
kc ochibili

0

Bạn có thể sử dụng Tùy chọn phức hợp Android - của Felipe Silvestre thư viện để lưu trữ các đối tượng tùy chỉnh của mình. Về cơ bản, nó sử dụng cơ chế GSON để lưu trữ các đối tượng.

Để lưu đối tượng vào prefs:

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();

Và để lấy lại nó:

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

Bưu kiện không phải là một cơ chế tuần tự hóa có mục đích chung. Lớp này (và API Parcelable tương ứng để đặt các đối tượng tùy ý vào một Parcel) được thiết kế như một phương thức truyền tải IPC hiệu suất cao. Do đó, không thích hợp để đặt bất kỳ dữ liệu Parcel nào vào bộ nhớ liên tục: những thay đổi trong việc triển khai cơ bản của bất kỳ dữ liệu nào trong Parcel có thể khiến dữ liệu cũ hơn không thể đọc được.
Marcos Vasconcelos

Tính năng này không được dùng nữa
IgorGanapolsky

0

Bạn có thể sử dụng GSON, sử dụng Gradle Build.gradle:

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

Sau đó, trong mã của bạn, ví dụ các cặp chuỗi / boolean với Kotlin:

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

Thêm vào SharedPrefs:

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

Bây giờ để truy xuất dữ liệu:

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())
}

Bưu kiện không phải là một cơ chế tuần tự hóa có mục đích chung. Lớp này (và API Parcelable tương ứng để đặt các đối tượng tùy ý vào một Parcel) được thiết kế như một phương thức truyền tải IPC hiệu suất cao. Do đó, không thích hợp để đặt bất kỳ dữ liệu Parcel nào vào bộ nhớ liên tục: những thay đổi trong việc triển khai cơ bản của bất kỳ dữ liệu nào trong Parcel có thể khiến dữ liệu cũ hơn không thể đọc được.
Marcos Vasconcelos

0

Sở thích chia sẻ chung (CURD) SharedPreference: để Lưu trữ dữ liệu dưới dạng các cặp khóa-giá trị với một lớp Kotlin đơn giản.

var sp = SharedPreference(this);

Lưu trữ dữ liệu:

Để lưu trữ dữ liệu String, Int và Boolean, chúng ta có ba phương thức có tên giống nhau và các tham số khác nhau (Nạp ​​chồng phương thức).

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

Truy xuất dữ liệu: Để truy xuất dữ liệu được lưu trữ trong SharedPreferences, hãy sử dụng các phương pháp sau.

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

Xóa tất cả dữ liệu: Để xóa toàn bộ SharedPreferences, hãy sử dụng mã bên dưới.

 sp.clearSharedPreference()

Xóa dữ liệu cụ thể:

sp.removeValue("user_name")

Loại sở thích được chia sẻ chung

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()
    }
}

Blog: https://androidkeynotes.blogspot.com/2020/02/shared-preference.html


-2

Không có cách nào để lưu trữ các đối tượng trong SharedPreferences, Những gì tôi đã làm là tạo một lớp công khai, đặt tất cả các tham số tôi cần và tạo các bộ cài và bộ nhận, tôi có thể truy cập các đối tượng của mình,


-3

Bạn có cần truy xuất đối tượng ngay cả sau khi ứng dụng tắt hoặc chỉ trong khi nó đang chạy?

Bạn có thể lưu trữ nó vào cơ sở dữ liệu.
Hoặc Đơn giản chỉ cần tạo một lớp Ứng dụng tùy chỉnh.

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>

Và sau đó từ mọi hoạt động làm:

((MyApplication) getApplication).getMyObject();

Không thực sự là cách tốt nhất nhưng nó hoạt động.


-6

Có. Bạn có thể lưu trữ và truy xuất đối tượng bằng Sharedpreference

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.