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

소스코드 포함 재질문 ) RecyclerView와 Sqlite 사용중 발생된 에러인데 도움좀 부탁드려요.

0 추천

이전 게시물로는 제가 만든 어설픈 소스가 제 질문을 물어보기엔 정보가 많이 부족했던거 같았네요.

제가 작성한 소스 구성이 일반적?(정상적이지) 이 못한거 같아 이전 질문이지만 다시 올려봅니다.

도음이 간절합니다. ㅠㅠ 

 

에러 코드 1) No adapter attached; skipping layout

에러 코드 2) attempt to re-open an already-closed object: SQLiteQuery: SELECT * FROM chatdb

에러 코드 3) 2번이 발생되지 않을때 나타 나더군요 Cursor on a null object reference

 

/// 글자 수 제한으로 일부는 이미지로 올려놓겠습니다. //

 

메인페이지

RecyclerView 소스 그러니까 messageAdapter 부분입니다.

messageAdapter.class

 

    private static final String TAG = "MessageAdapter";
    private Context context;
    private Cursor adapterCursor;
    private String uid;
    private List<ChatModel.Comment> comments = new ArrayList<>();


    public MessageAdapter(Context context, Cursor mCursor, String uid) {
        this.context = context;
        this.adapterCursor = mCursor;
        this.uid = uid;
    }

    
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message,parent,false);
        return new MessageViewHolder(view);
    }

    
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        MessageViewHolder messageViewHolder = ((MessageViewHolder)holder);

        if (!adapterCursor.moveToPosition(position))
            return;

        if (adapterCursor.getString(adapterCursor.getColumnIndex(ChatContract.ChatEntry.COLUM_UID)).equals(uid)) {
            messageViewHolder.textView_message.setText(adapterCursor.getString(adapterCursor.getColumnIndex(ChatContract.ChatEntry.COLUM_COMMENT)));
            ....중략...
            }
        }
    }
    public class MessageViewHolder extends RecyclerView.ViewHolder {

        public TextView textView_message;
        ....중략......
        public TextView right_count;

        public MessageViewHolder(View view) {
            super(view);

            layout_destination = view.findViewById(R.id.messageItem_layout_destination);
            .... 중략 ........

        }


    }

    @Override
    public int getItemCount() {
        int count = adapterCursor.getCount();
        return count;
    }

    public void swqpCursor(Cursor newCursor){
        if(String.valueOf(adapterCursor).equals("null")) {
            adapterCursor.close();
        }
        this.adapterCursor = newCursor;
        this.notifyDataSetChanged();
    }

}

 

아 그리고 SQliteHelper 부분입니다. 

db = ChatDBHelper.getInstance(getApplicationContext());

메인에 요 부분이죠 ..

nickeun (540 포인트) 님이 2018년 4월 10일 질문
nickeun님이 2018년 4월 10일 수정
SQliteHelper 사용법과 Cursor에 대한 제 이해도가 아직 부족한건지
DB결과를 Cursor에 담은걸 다시 List로 담아 사용하는걸로 변경했습니다.
attempt to re-open an already-closed object: SQLiteQuery: SELECT * FROM chatdb
이 에러때문에 Cursor null 에러가 해결된거지도 확인이 안되고
얼떨결에 문제를 피하기만 한거 같네요. 근본적인 우회도 아니고 엉터리로 피한거만 같네요

3개의 답변

0 추천

다음 코드들이 의심 스럽네요.

mCursor.close();


if(String.valueOf(adapterCursor).equals("null")) {
	adapterCursor.close();
}

 

디자이너정 (42,810 포인트) 님이 2018년 4월 10일 답변
댓글 다시 달게요... 수정하였습니다.
String.valueOf(adapterCursor).equals("null") == true 이면
adapterCursor이 null이라는 이야기인데,
그럼 다음 close할때 "Cursor on a null object reference" exception이 나지 않을까요?
"Cursor on a null object reference" exception 발생했습니다.
그래서 mCursor = db.getAllChat(); 에서 데이터를 못가져왔다 빈값인가 확인해
보니 반복문 돌려보면 그 안에 데이터는 있더라고요.
지금은 attempt to re-open an already-closed object: SQLiteQuery: SELECT * FROM chatdb 이에러가 발생하고있습니다. ㅠ;
끝이없이 나오는 에러 감을 못잡고 있네요  저의 글에 관심 가져주셔서 감사합니다.

아 추가적인 질문이 되는거 같은데 mCursor 안에 내용을을 while 문으로 돌려
확인해볼때 어떤 테이블 네용은 7개 면 안에 내용이 다 출력 됩니다
그런데 어떤 테이블 내용은  

I/System.out: 1523340843361
I/chatty: uid=10085(com.example.krmai.nychat0001) identical 11 lines
I/System.out: 1523340843361
이런식으로 나오고 말거든요;;  구글링해보면 짧은 시간안에 만은 로그 기록은 제한된다라는데 그런 이유에서 저렇게 마지막 부분만 나오는건가요?
그렇다고 하기엔 일반 숫자 1~20 출력 이런건 다 나오던데요.. ㅠ
--;

mCursor.close(); 을 빼세요;;;;
네.. 지금은 다 빼놓은 상태입니다.ㅠㅠ
지금은  attempt to re-open an already-closed object: SQLiteQuery: SELECT * FROM chatdb  에러가 발생중이고요.

댓글 달아주고도 많이 답답하시죠? ㅠ;;;
0 추천

public void swqpCursor(Cursor newCursor){
        if(String.valueOf(adapterCursor).equals("null")) {
            adapterCursor.close();
        }
        this.adapterCursor = newCursor;
        this.notifyDataSetChanged();
    }
이거 말씀하시는거죠? 이후에는 없어요
대화 내용 갱신을 SQlite에 긁어와 재구성 해주는 부분이고요  
전송 버튼을 누르면 
 mCursor = db.getAllChat();
DB내용을 가져오고 그걸 
messageAdapter.swqpCursor(mCursor); 를 통해서 전송된다고 생각해서
짜놓은 코드입니다.
RecyclerView에서는 Cursor 값을 받아 해당 전역변수에 전달되고
this.notifyDataSetChanged(); 변경됨을 알리는걸로 짜놓은 겁니다 

recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
messageAdapter = new MessageAdapter(getApplicationContext(), mCursor, uid);
                recyclerView.setAdapter(messageAdapter);
요 부분은 원래 사용할때마다 코드가 실행되야하는 부분인지
헷갈리네요. 처음 한번 생성해놓고 messageAdapter.swqpCursor(mCursor);
로만 사용하면 되지 않나 싶어 소스를 건드리다 에러 덩어리로 만들어 버렸네요
잘 안된다고 너무 건드렸나 봅니다.

모든 사건의 발단은 recyclerView를 저렇게 매번 실행할때마다 작동시켜야하나
수정하다 messageAdapter.swqpCursor(mCursor)부분에서
Cursor on a null object reference  에러가 발생하면서 그거 잡다가 일이 이렇게
꼬여버렸네요.;
원래 문제가 있는 구성여서 탈이 날게 난건지 너무 답답해서 이렇게 올리고있습니다.

String.valueOf(adapterCursor).equals("null") 이부분을 뭐이렇게 조잡하게 해놨냐 싶으시겠지만 
Cursor null 에러 해결해보겟다고 바꿔놓은 부분입니다 ㅠ

nickeun (540 포인트) 님이 2018년 4월 10일 답변
0 추천
해결됐습니다 ^^

일단 Cursor를 이용하면서 Cursor의 위치 변화에 대한 이해도 부족으로 벌어진 일 과

close를 아무곳에서 하면 안된다도 배웠습니다 댓글 감사합니다.

 

이제 제가 생각했던 흐름대로 움직여주네요
익명사용자 님이 2018년 4월 11일 답변
...