[Android 07] SharedPreferences sống thử với Singleton
1. Singleton là gì?
- Singleton pattern là một lớp nhằm đảm bảo rằng chỉ có 1 instance của nó được tạo ra và cung cấp 1 cách giao tiếp chung bên trong nó cho những tác nhân bên ngoài. Nói chung nó sẽ đảm bảo tính nhất quán (consistency).
- Singleton quản lý việc truy cập khá tốt vì chỉ có 1 instance duy nhất.
- Có thể cải tiến các tác vụ và các thể hiện do pattern, sẽ được kế thừa và tùy biến thông qua thể hiện của lớp con.
- Quản lý số lượng các instance của 1 lớp,
- Flexible hơn so với việc dùng 1 lớp có thuộc tính static (Lí do bởi vì static có thể sử dụng 1 instance duy nhất, còn singleton pattern cho phép quản lý instance tốt hơn và dễ dàng tùy biến).
2. Khi nào dùng Singleton?
- Khi cần instance duy nhất của 1 lớp.
- Khi instance đó có khả năng mở rộng thông qua kế thừa, do đó các dev có thể sử dụng kế thừa mà không cần thay đổi mã code.
3. Cách thức Singleton được tạo.
- Định nghĩa thuộc tính private và static trong lớp Singleton
- Định nghĩa constructor thành protected hoặc private để người dùng không thể tạo trực tiếp từ class.
- Định nghĩa accessor trong getInstance() thành public và static, đồng thời kiểm tra xem nó đã được khởi tạo hay chưa, tránh trường hợp getInstance() trả về null, nguy hiểm trong các trường hợp đa luồng và bất đồng bộ.
- Cẩn thận kiểm tra nếu sử dụng multithreading vì ví dụ trường hợp có hai threads có thể gọi phương thức sinh object tại cùng một thời điểm và 2 instance được tạo ra. Lúc này có thể sử dụng classLoader hoặc double-check-locking. Nó cũng tương tự Immutable trong java core vậy. 😀
4. Sử dụng SharedPreferences và Singleton.
Hãy xem ví dụ sau đây, tất cả đã được chú thích.
Hãy xem ví dụ sau đây, tất cả đã được chú thích.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | package project.android.xml; import android.content.Context; import android.content.SharedPreferences; import com.google.gson.Gson; import java.util.Objects; /** * Created by GUT81HC on 4/11/2018. */ public class SharedPreferencesManager { public static final String PREF_NAME = "project.android.xml"; /** * Sử dụng Singleton Class để truy cập SharedPreferencesManager. * Được khởi tạo 1 lần duy nhất lúc khởi chạy component của ứng dụng * Sử dụng phương thức static khởi tạo (Sử dụng ApplicationContext) */ private static final String TAG = SharedPreferencesManager.class.getName(); private static SharedPreferencesManager sharedPreferencesManager; private SharedPreferences sharedPreferences; /** * Khởi tạo Constructor cho SharedPreferencesManager * * @param context: lấy phương thức getSharedPreferences */ private SharedPreferencesManager(Context context) { sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); } /** * Lấy instance của SharedPreferencesManager nếu đã được khởi tạo, hoặc ném ra 1 exception IllegalStateException. * * @return */ public static SharedPreferencesManager getInstance() { if (sharedPreferencesManager == null) { throw new IllegalStateException("Have not initialized yet"); } return sharedPreferencesManager; } /** * Khởi tạo SharedPreferencesManager. * Nếu context bằng null, trả về NullPointerException. * Nếu instance của SharedPreferencesManager bằng null, đồng bộ hóa bằng cách lock nó lại, dùng synchonized * để khởi tạo lại instance của SharedPreferencesManager bằng từ khóa new. * * @param context */ public static void initialize(Context context) { if (context == null) { throw new NullPointerException("ApplicationContext is null"); } if (sharedPreferencesManager == null) { synchronized ((SharedPreferencesManager.class)) { if (sharedPreferencesManager == null) { sharedPreferencesManager = new SharedPreferencesManager(context); } } } } private static String createJsonFromObject(Object object) { return new Gson().toJson(object); } /** * Trả về giá trị SharedPreferences từ android.content * * @return */ private SharedPreferences getPrefs() { return sharedPreferences; } /** * Xóa hết tất cả prefs trong SharedPreferences. * Sử dụng apply thay vì commit nếu muốn bất đồng bộ và không cần trả về kết quả thực thi ổn hay không. */ public void clearPrefs() { SharedPreferences.Editor editor = getPrefs().edit(); editor.clear(); editor.apply(); } /** * Xóa một key trong SharedPreferences. * * @param key: Chấp nhận primitive data. */ public void removeKey(String key) { getPrefs().edit().remove(key).apply(); } /** * Tìm key tồn tại hay không trong SP. * * @param key * @return if contains key in S.P */ public boolean containsKey(String key) { return getPrefs().contains(key); } /** * Thêm 1 key String và value vào SP, tương tự như các primitive data khác. * * @param key * @param value */ public void setString(String key, String value) { SharedPreferences.Editor editor = getPrefs().edit(); editor.putString(key, value); editor.apply(); } /** * Thêm key và value với kiểu Object class vào trong SP. * * @param key * @param object: Object đã được cast thành String và sẽ sử dụng Gson để map dữ liệu thành object ngược lại khi reverse. * @param <M> */ public <M extends Objects> void setObject(String key, M object) { String value = createJsonFromObject(object); SharedPreferences.Editor editor = getPrefs().edit(); editor.putString(key, value); editor.apply(); } /** * Tương tự put Object vào SP, việc put Collection vào SP cũng sử dụng Gson để cast Object thành String. * * @param key: String * @param dataCollection : Collection Object. * @param <C> : Generic Colletion Object. */ public <C> void setCollection(String key, C dataCollection) { SharedPreferences.Editor editor = getPrefs().edit(); String value = createJsonFromObject(dataCollection); editor.putString(key, value); editor.apply(); } /** * Lắng nghe thay đổi của SP thông qua 1 listener. * * @param listener */ public void registerPrefsListener(SharedPreferences.OnSharedPreferenceChangeListener listener) { getPrefs().registerOnSharedPreferenceChangeListener(listener); } } |
Nhận xét
Đăng nhận xét