운기의 블로그
#3. 나만의 메모장 만들기 / ROOM error: AppDatabase() has private access in AppDatabase 문제 해결 / 싱글톤 본문
#3. 나만의 메모장 만들기 / ROOM error: AppDatabase() has private access in AppDatabase 문제 해결 / 싱글톤
운띠야 2020. 3. 7. 20:03저번에 이어서 saveMemoActivity를 만들어 보겠습니다.
mainActivity에서 현재 저장되어있는 메모 상태를 본 다면,
saveMemoActivity에서는 메모를 작성하고 안드로이드 로컬 database에 작성한 메모를 넣어 줄려고합니다.
기존에 SQLite에 대한 추상화 레이어를 제공하여 보다 원할하게 사용할 수 있도록 도와줍니다.
사용자는 DAO (Data Access Objects ) 인터페이스를 통해서 데이터베이스에 값을 저장하기도하고
저장된 값을 불러와서 사용 할 수 있습니다.
Room 사용하기
Room을 사용할 때, 보통 LiveData를 사용해서 mvvm 패턴에서 옵저버패턴을 이용하여 사용 하지만..
아직 저는 부족한 관계로.. 디자인패턴없이 사용했습니다
종속성 추가
https://developer.android.com/jetpack/androidx/releases/room?hl=ko#declaring_dependencies
자바의 경우
def room_version = "2.2.3"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
추가해주시면됩니다. 최신버전은 찾아서 바꾸 주시는 센스 !!
종속성도 추가했으니 사용해보겠습니다.
(아래 설명은 그림 1을 참조합니다.)
Room을 사용하기 위해서
RoomDatabase , Data Access Object, Entity 해당하는 클래스를 3개 만들어 줍니다.
( -> 뒤에 적힌건 제가 만든 클래스 명입니다. )
1. Entity -> User
User 클래스에서는 자신이 사용할 항목을 미리 설정해 줍니다.
제가 사용 메모장에서 사용할 것은 String des 변수인데 문장 자체를 기본키로 사용 하려니까 에러가 떴습니다.
그래서 int 형 id라는 변수를 만들고 autoGenerate를 사용해서 id값이 기본키가 될 수 있게 만들어 줬습니다.
생성자에서는 id 값을 빼고 만들었습니다.
위에 annotation을 사용해서 Entity라는걸 알려주고 table 이름을 선언해 줍니다.
이렇게 하면 Entity를 완성해줬습니다.
2. Data Access Object -> UserDao
Dao 객체는 데이터 베이스에 접근 하는데 사용 되는 메서드를 담고 있습니다.
데이터를 삽입 삭제 출력과 같은 메서드를 작성해줍니다.
@Dao , @Insert, @Update, @Delete, @Query 라는 역할을 알려주기 위해 annotation을 추가해 줍니다.
3. RoomDatabase -> AppDatabase
마지막으로 Database를 만들어 줄 겁니다.
개인적으로 이 부분이 제일 힘들었습니다. 이유는 아래 설명과 함께 알려드리겠습니다.
안드로이드 개발자 문서에서 데이터베이스 개체를 단일 프로세스앱에서 실행 될 경우 싱글톤 디자인 패턴을 따라야 한다고 합니다.
싱글톤 패턴은 어떤 클래스를 최초 단 한번만 !! 생성하여 메모리에 할당하고 그 메모리를 참조해서 사용하는 디자인 패턴을 말합니다.
방법은 생성자를 private로 만들어서 다른 곳에서 생성자를 호출해도 생성이 불가하게 한 후 getInstance() 메서드를 만들어서 호출하여 사용하는 방식입니다.
싱글톤 패턴으로 AppDatabase를 호출하게 만들었습니다.
우선 기본적으로 Room은 메인스레드에서 사용하게 되면, 실행이 되지 않습니다. 그래서 혼자서 앱을 만들 때, 실행이 잘되는 여부를 확인하고 싶으면 .allowMainThreadQueries()를 사용하여 테스트를 하셔야합니다.
하지만 !!
앱을 실행시켰을 때
error: AppDatabase() has private access in AppDatabase
이런 에러가 났습니다.
인터넷에 정말 열심히 찾아봤는데
대부분의 답은 kotiln을 사용하겠다는걸 gradle에 추가해줘야한다고 설명을 해놨습니다.
" 나는 자바인데 왜 이걸 추가해줘야 되는거지? " 라는 의문을 가지고 따라해봤지만, 역시는 역시....
실행이 되지 않습니다.
몇일간 고민하고, 물어본 결과 !!
추상클래스 때문이였습니다.
추상 클래스에서 어차피 재정의해서 사용해야 하는데, private로 접근지정자를 설정해 두면, 가져다 재정의 해서 쓸 수 도 없기 때문에 만들어줘도 사용이 불가능 하기 때문에 애초에 사용해서는 안되는 것이였습니다.
그렇기 때문에 혹시나 이런 문제로 어려움을 겪고 계신다면 꼭 확인해주세요
" 내가 추상클래스에서 생성자를 private으로 만들어 주었나 ?!! "
SaveMemoActivity
메모를 작성하는 액티비티로 돌아와서 추가해 줍니다.
기존에 databinding은 수정하고 setconentView를 사용해서 XML을 사용했습니다.
Database 객체를 만들어서 getInstance 메서드를 이용해서 생성해줍니다.
onCreateOptionsMenu는 디스크 모양을 앱 오른쪽 상단에 넣어 줍니다.
그리고 onOptionsItemSelected 함수를 만들어서 디스크 모양을 클릭하게 되면
Database의 객체인 db에 만든 userDao() 인터페이스에 만들어둔 insert 함수를 실행시키고,
결과로 SaveMemoActivity에 만들어 둔 textView에 결과가 출력 될 수 있게 테스트 했습니다.
getAll( ) 을 사용해서 로컬 디비에 저장되어 있는 애들이 전부 출력되는지 확인해 줍니다.
실행화면
EdItText에
- 룸 테스트 입니다. - 를 입력하고
오른쪽 상단에 보이는 디스크 모양을 클릭하면 저장이 되게 만들었습니다.
저장버튼(디스크 모양)을 클릭하게 되면 이전에 제가 테스트했던 내용과 방금 입력했던 내용이
로컬 데이터베이스에 잘 들어가 있는 걸 확인 할 수 있습니다.
전체 코드를 보고싶으면
1. error: AppDatabase() has private access in AppDatabase 에러 문제 발생한 시점
https://github.com/leewoongi/MemoPad/commit/84c07821d0b90a7a34926157af2612edd934b912
2. 에러 해결 한 부분 /
들어가시면 local.properties는 무시해주세요. 집에서 데스크탑 으로 하다가 노트북으로 해서 그렇습니다.
https://github.com/leewoongi/MemoPad/commit/dc78411138a553dc6f805e36e22103c6b7de48be
'안드로이드' 카테고리의 다른 글
#5. 나만의 메모장 만들기 / Database에 저장된 내용 리사이클러뷰에 바로 update 하기 / 리사이클러뷰 아이템 삭제 및 ROOM, 로컬DB에서 삭제하기 / JAVA (0) | 2020.03.30 |
---|---|
#4. 나만의 메모장 만들기 / Database에 저장된 내용 리사이클러뷰에 넣기 / Dialog + editText (0) | 2020.03.17 |
#2. 나만의 메모장 만들기 UI (0) | 2020.02.28 |
#1 안드로이드 , 나만의 메모장 만들기 (0) | 2020.02.27 |
기상청 코드 , 위도 경도 변환 및 카카오 지도 마커 찍기 #6 (0) | 2020.01.19 |