⚠️ 2021.01.21에 작성된 글입니다 ⚠️
SharedPreferences에 ArrayList 저장하기
[Android] SharedPreferences 데이터 저장하기에서 살펴봤듯, SP로 데이터를 저장할 때에는 저장이 가능한 데이터타입이 한정적이다. 따라서 [Android] SharedPreferences 객체 저장하기 때와 같이, ArrayList를 저장할 때에도 gson을 사용해 ArrayList를 String(JSON)으로 변환해 SP에 넣고, 꺼내올 때도 가져온 String을 gson을 통해 ArrayList 형태로 변환해야 한다.
작업 흐름:
ArrayList, GSON을 사용하여
JSON으로 변환
↓
SharedPreferences에 저장
↓
저장된 JSON 꺼내와
GSON 사용하여 ArrayList로 변환
JSON을 ArrayList로 변환할 때 fromJson()메소드를 사용하여 두번째 인자의 형식으로 첫번째 인자를 변형한다.
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
if (json == null) {
return null;
}
StringReader reader = new StringReader(json);
T target = (T) fromJson(reader, typeOfT);
return target;
}
JSON을 객체로 변환할 때에는
User user = gson.fromJson(value, User.class);
이렇게 두번째 인자로 해당 객체의 클래스를 넣어주면 되지만, ArrayList의 경우에는 1)TypeToken이라는 객체를 활용해야 한다. 혹은 2)ArrayList 자체를 담는 객체를 만들어 위처럼 객체로 변경한 뒤 ArrayList를 빼오는 방법이 있다.
TypeToken 이용하기
TypeToken
: GSON 라이브러리에서 제공하는 제네릭타입(generic type)을 나타내는 클래스
public class TypeToken<T> extends Object
Represents a generic type T. Java doesn't yet provide a way to represent generic types, so this class does. Forces clients to create a subclass of this class which enables retrieval the type information even at runtime.
For example, to create a type literal for List<String>, you can create an empty anonymous inner class:
TypeToken<List<String>> list = new TypeToken<List<String>>() {};
This syntax cannot be used to create type literals that have wildcard parameters, such as Class<?> or List<? extends CharSequence>.
- gson javadoc.io
protected TypeToken() {
this.type = getSuperclassTypeParameter(getClass());
this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
this.hashCode = type.hashCode();
}
ArrayList 저장하기
ArrayList<List> lists;
Gson gson = new GsonBuilder().create();
SharedPreferences preferences;
SharedPreferences.Editor editor;
final String PREF = "list";
final String LIST = "arrayList";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
preferences = getSharedPreferences(PREF, 0);
editor = preferences.edit();
editor.remove(LIST).apply(); // 기존에 있던 정보 지우기(초기화)
ArrayList<List> saveList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
saveList.add(new List("jake", "London", "student"));
saveList.add(new List("tom", "Seoul", "CEO"));
saveList.add(new List("chris", "Tokyo", "professor"));
saveList.add(new List("peter", "MexicoCity", "teacher"));
}
// ArrayList를 SP에 저장하기
editor.putString(LIST, gson.toJson(saveList)).apply();
...
}
저장한 정보 ArrayList로 가져오기
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
String value = preferences.getString(LIST, null);
if (value != null) {
// SP에서 데이터 가져와 ArrayList로 변환하기
lists = gson.fromJson(value, new TypeToken<ArrayList<List>>() {
}.getType());
adapter = new ListAdapter(lists);
recyclerView.setAdapter(adapter);
} else
Toast.makeText(getApplicationContext(), "list is null", Toast.LENGTH_LONG).show();
}
객체 활용하기
ListArray.class : ArrayList를 가지고 있는 클래스 만들기
public class ListArray {
ArrayList<List> arrayList;
public ListArray() {
}
public ListArray(ArrayList<List> arrayList) {
this.arrayList = arrayList;
}
public ArrayList<List> getArrayList() {
return arrayList;
}
public void setArrayList(ArrayList<List> arrayList) {
this.arrayList = arrayList;
}
}
ListAdapter에 생성자 추가
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ListViewHolder> {
ArrayList<List> lists = new ArrayList<>();
public ListAdapter(ArrayList<List> lists) {
this.lists = lists;
}
public ListAdapter(ListArray listArray) {
this.lists = listArray.getArrayList();
}
...
}
ArrayList 저장하기
ListArray arrayObject = new ListArray();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
for (int i = 0; i < 5; i++) {
...
}
// ArrayList를 객체에 넣기
arrayObject.setArrayList(saveList);
// 객체를 SP에 저장하기
editor.putString(LIST, gson.toJson(arrayObject)).apply();
저장한 정보 가져오기
...
// SP에 저장된 정보 가져오기
String value = preferences.getString(LIST, null);
// 가져온 정보 객체로 변환 및 저장하기
ListArray sampleList = gson.fromJson(value, ListArray.class);
// 객체에서 ArrayList 가져와 세팅하기
lists = sampleList.getArrayList();
adapter = new ListAdapter(lists);
recyclerView.setAdapter(adapter);
...
참고자료
Gson (Gson 2.6.2 API) (javadoc.io)
TypeToken (Gson 2.6.2 API) (javadoc.io)
GSON Type 정의 관련 정리 :: Wired dlog (tistory.com)
후니훈의 모바일 세상 :: JSonArray를 GSON 을 이용해 ArrayList<Object> 로 변경. (tistory.com)
공부하며 정리한 글입니다. 내용에 대한 피드백은 언제나 환영입니다.
'Android' 카테고리의 다른 글
[Android] 디데이 계산기 (0) | 2022.10.22 |
---|---|
[Android] WebView 웹뷰 (0) | 2022.10.22 |
[Android] SharedPreferences 객체 저장하기 (0) | 2022.10.22 |
[Android] SharedPreferences 데이터 저장하기 (0) | 2022.10.22 |
[Android] RecyclerView CRUD (0) | 2022.10.22 |