original source :  https://medium.com/@amit.bhandari/storing-java-objects-other-than-primitive-types-in-room-database-11e45f4f6d22

compile "android.arch.persistence.room:runtime:1.0.0-alpha3"annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha3"compile 'com.google.code.gson:gson:2.6.2'

First 2 lines for including Room DB in our project and 3rd one is Gson which we will use to convert our object to String.

Our modified User.java looks something like this. Even though you can’t see any getter or setter method here, you need to include them or make the fields public for Room to access it.

User.java

@Entitypublic class User {   @PrimaryKey   private int uId;   private String uName;   private ArrayList<String> uPets = new ArrayList<>();   public User() {   }   public User(int id, String name, List<String> pets){      this.uId = id;      this.uName = name;      this.uPets.addAll(pets);   };   //getters setters removed for brevity}

User DAO stays more or less the same. You can include methods to fetch particular user from user id or name, I will leave that as an exercise for you.

UserDAO.java

@Daopublic interface UserDAO {   @Insert(onConflict = REPLACE)   void insertUser(User user);   @Query("SELECT * FROM User")   List<User> getUsers();   //include any methods to fetch specific user   // @Query("SELECT * FROM User")}

And our UserDB will also stay the same except small difference.

UserDB.java

@Database (entities = {User.class},version = 1)@TypeConverters({Converters.class})
public abstract class UserDB extends RoomDatabase {   public abstract UserDAO userDAO();}

Noticed that @TypeConverters annotation we provided along with @Database annotation, this will be the class which will tell Room how to convert ArrayList object to one of SQLite data type. We will implement methods to convert ArrayList to String for storing it in DB and String back to ArrayList for getting back original User object.

Type Converter specifies additional type converters that Room can use. The TypeConverter is added to the scope of the element so if you put it on a class / interface, all methods / fields in that class will be able to use the converters.

Without further delay, we will see how our type converter looks in our case.

UserDAO.java

public class Converters {   @TypeConverter   public static ArrayList<String> fromString(String value) {      Type listType = new TypeToken<ArrayList<String>>() {}.getType();      return new Gson().fromJson(value, listType);   }   @TypeConverter   public static String fromArrayLisr(ArrayList<String> list) {      Gson gson = new Gson();      String json = gson.toJson(list);      return json;   }}

As you can see, we have 2 methods in TypeConverter.

  1. public static String fromArrayLisr(ArrayList<String> list) : This method takes our arraylist object as parameter and returns string representation for it so that it can be stored in Room Database. Very simple and easy way to convert any object to string is converting it into its JSON equivalent. Just creating Gson object and calling toJson method with our object as parameter is enough.
  2. public static ArrayList<String> fromString(String value) : While reading data back from Room Database, we get JSON form of our arraylist which we need to convert back. We will use Gson method fromJson by providing JSON string as parameter. But while converting back, we also need to provide the class of original object (in our case, arraylist), but providing arraylist is not enough here as Gson will not be able know what kind of list it has to form. That’s why we used Type to provide the type of list we want Gson to form for us from the JSON string.

.

.

.

.

참고사항) @Bindable 에 대하여

https://medium.com/@jencisov/androids-data-binding-s-baseobservable-class-and-bindable-annotation-in-kotlin-1a5c6682a3c1

https://www.youtube.com/playlist?list=PLJJzW__bab3SF33vwvlA_F7PPN6NxkHdQ

image
image
image
image
image
image
image
image
image

.

.

.

.

room dependencies추가 

image
image
image

.

.

.

.

entity class

image
image

.

.

.

.

DAO 만들기

image

.

.

.

.

database 만들기

image

.

.

.

.

실제 사용 예시

image
image

allowMainThreadQueries()를 통해 메인쓰레드에서도 query가 작동가능하게 된다.

본래는 다른 thread에서 해줘야 한다.

image

.

.

.

.

room database callback 

onCreate() 데이터베이스가 생성될때 호출된다.

onOpen()은 데이터베이스가 열릴때 호출된다

image
image
image

.

.

.

.

.

.

Room with coroutines

10분분량 개념잡기 좋다.

https://youtu.be/CcaCpRCACzU

.

.

.

.

.

한국사는 외국인 개발자 설명 Room with coroutines

https://youtu.be/Rm_B32ZB7s4

image

아래는 coroutines사용을 위해 suspend를 추가한 모습

image

이 개발자는 기본 Fragment를 extend해서 coroutine의 기능을 추가하고 이를 모든 fragment에 사용하려고 한다.

image
image

아래는 Context를 extension func 추가 해서 toast를 쉽게 하는 팁설명

image
image

.

.

.

.

.

jetpack room with coroutines in kotlin

https://youtu.be/kF0TPehhIx0

image
image
image
image
image
image

.

.

.

.

참고사항)

room sqlite에 primitive 타입이 아닌 다른 데이터를 저장해야 하는 경우 (obj를 json string으로 변경해서 sqlite database에 저장한다.)

https://medium.com/@amit.bhandari/storing-java-objects-other-than-primitive-types-in-room-database-11e45f4f6d22

https://youtu.be/W0ag98EDhGc

androidTest는 android component관련 테스트할때 사용한다.

일반 java, kotiln 테스트는 test를 이용한다.

.

.

필요한 dependencies

.

.

원본 소스 코드 (테스트될 코드)

.

.

오른쪽 클릭

.

.

JUnit4가 안드로이드와 더 잘 작동 (2020 기준)

.

.

.

.

테스트 코드