마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

room 데이터베이스의 특정 행의 내용은 어떻게 수정하는 건가요?? 도와주세요..

0 추천

* A액티비티안에 리사이클러뷰가 존재합니다. 리사이클러뷰 중 수정하고 싶은 아이템을 누르면 글을 상세하게 볼 수 있는 B액티비티가 띄워지고, B액티비티에서 글을 수정하고 BackPress 버튼을 누르면 수정된 글로 ROOM 데이터베이스 행이 수정되게끔 만들고 싶습니다. 

A액티비티

<A액티비티>                                           <B액티비티>                            <B액티비티 - 수정 후>

 

1. ROOM 데이터베이스를 업데이트 하고자 B액티비티의 BackPress 부분에 넣은 코드입니다.

  * position 변수는 A액티비티의 포지션 값을 B액티비티에서 position = intent.getExtras().getInt("position"); 로 넘겨받아 설정하였습니다.

2. ROOM Dao의 업데이트 코드 부분입니다.

3. 데이터베이스의 repository 부분입니다.

3. ViewModel 부분입니다.

 

-> 코드를 위와 같이 구성한 후 실행을 시켰더니 아래와 같은 에러가 뜨며 앱의 튕김현상이 일어났습니다.

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
    Process: org.jh.todomemo, PID: 31384
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$4.done(AsyncTask.java:399)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
     Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
        at org.jh.todomemo.db.entity.writingMemoRepository$updateAsyncTask.doInBackground(writingMemoRepository.java:87)
        at org.jh.todomemo.db.entity.writingMemoRepository$updateAsyncTask.doInBackground(writingMemoRepository.java:76)
        at android.os.AsyncTask$3.call(AsyncTask.java:378)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:919) 
D/Toast: show: focusDisplayId = 0, isFocusInDesktop = false mCustomDisplayId=-1
I/Process: Sending signal. PID: 31384 SIG: 9

 

이럴 경우, 어떻게 해야 에러를 해결하고 문제없이 특정 데이터베이스의 행을 수정할 수 있을까요??

도와주세요... 

안드11 (330 포인트) 님이 2021년 1월 8일 질문
코드를 보고 궁금한게 있는데 왜 repository에 AsyncTask를 사용하시나요? Repository를 Domain 계층인데 때문에 안드로이드 시스템이 종속된 AsyncTask를 사용하시는 것은 좀 의아하네요. 게다가 AsyncTask는 최근에 deprecated되었구요. ViewModel, Repository 등의 라이프사이클 관련 클래스 빼고는 안드로이드 시스템의 클래스를 사용하지 않는 것이 통상적인 규칙입니다.
AsyncTask를 자주 사용하기도 했었고 다른 비동기처리 방법보다 편하여 사용하였습니다.
아래 클래스를 가져다 써보세요.
https://github.com/android/architecture-components-samples/blob/main/GithubBrowserSample/app/src/main/java/com/android/example/github/AppExecutors.kt

아래와 같이 사용합니다.

appExecutors.diskIO().execute {
     // DB 관련동작
     dao.updateWritingMemo(memo);                   
}

appExecutors.neworkIO().execute {
     // 네트워크나 관련동작
                        
}

appExecutors.mainThread().execute {
      // UI쓰레드 관련동작
}
알려주셔서 감사합니다!

1개의 답변

0 추천
 
채택된 답변

에러에 

Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
        at org.jh.todomemo.db.entity.writingMemoRepository$updateAsyncTask.doInBackground

라고 나오네요. writingMemos[index] 에서 index이 범위가 writingMemos를 벗어났습니다.

public static class UpdateAsyncTask extends AsyncTask<WritingMemo, Void, Void> {
      private final  WritingMemoDao dao;
  
     UpdateAsyncTask(WritingMemoDao dao) { 
          this.dao = dao;
     }

    @Override
    protected doInBackground(final WritingMemo...writingMemos) {
          WritingMemo memo  = writingMemos[0];
          if (memo== null) {
               throw new NoSuchElementFoundExcption("You must pass memo instance.");
         }

         dao.updateWritingMemo(memo);
    }
}

public void update(int index, WritingMemo writingMemo) {
     writingMemoRepository.update(writingMemo);
}

 ViewModel에서 WritingMemo를 하나만 넘기기 때문에 인덱스를 넘기실 필요가 없습니다. 그리고 메모가 배열이고 배열 안에 있는 메모를 저장할 때도 인덱스를  AsynTask에 넘기지 마시고 ViewModel에서 인덱스를 검사한 다음 WritingMemo 인스턴스만 넘기세요.

 

 

spark (226,420 포인트) 님이 2021년 1월 8일 답변
안드11님이 2021년 1월 9일 채택됨
...