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

Cursor에 관한 오류 ...

0 추천
// 쿼리 수행 , 외부 메모리
		mVideoCursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, null,null, MediaStore.Images.Media.DATE_ADDED + " desc ");
		startManagingCursor(mVideoCursor);
		if (mVideoCursor != null && mVideoCursor.getCount() > 0) {
			// 컬럼 인덱스 (썸네일 ID , 이미지 데이타)
			int videoIDCol	=	mVideoCursor.getColumnIndex(MediaStore.Video.Media._ID);
			int videoName	=	mVideoCursor.getColumnIndex(MediaStore.Video.Media.DISPLAY_NAME);
			int videoSize	=	mVideoCursor.getColumnIndex(MediaStore.Video.Media.SIZE);
			int videoTitle	=	mVideoCursor.getColumnIndex(MediaStore.Video.Media.TITLE);
			int videoDataCol	=	mVideoCursor.getColumnIndex(MediaStore.Video.Media.DATA);
			int videoDuration=	mVideoCursor.getColumnIndex(MediaStore.Video.Media.DURATION);
			int videoDate	=	mVideoCursor.getColumnIndex(MediaStore.Video.Media.DATE_ADDED);
			int videoResolution=	mVideoCursor.getColumnIndex(MediaStore.Video.Media.RESOLUTION);
			

			while (mVideoCursor.moveToNext()) {
				ThumbVideoInfo thumbInfo = new ThumbVideoInfo();

				thumbInfo.setmVideoId(mVideoCursor.getString(videoIDCol));
				thumbInfo.setmVideoData(mVideoCursor.getString(videoDataCol));
				thumbInfo.setmVideoName(mVideoCursor.getString(videoName));
				thumbInfo.setCheckedState(false);

				mThumbVideoInfoList.add(thumbInfo);

				returnValue++;
			}
		}
		mVideoCursor.close();


// 실제 경로 찾기
	private String getPath(Uri uri)
	{
	    String[] projection = { MediaStore.Images.Media.DATA };
	    cursor = managedQuery(uri, projection, null, null, null);
	    startManagingCursor(cursor);
	    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
	    cursor.moveToFirst();
	    String result = cursor.getString(column_index);
	    return result;
	}

@Override
	protected void onStop() {
		if(mVideoCursor != null && mVideoCursor.isClosed()){
			mVideoCursor.close();
		}
		if(cursor != null && cursor.isClosed()){
			cursor.close();
		}
		super.onStop();
	}

동영상과 관련된 프로젝트 만들고 잇습니다. 하지만 CURSOR 구조에 대한 부분이 부족하여 해결을 하지 못하게 정체상태에 빠지게 되었습니다. 구글링을 검색해보니 , Cursor close 가 안됬다 , cursor 를 다시 호출한다는 말이 나왔습니다.

 

 

소스가 다 안올라가 위 코드는 cursor 가 쓰이는 부분만 잘라서 올렸습니다.

witsht (350 포인트) 님이 2015년 8월 26일 질문
08-26 11:24:47.775: E/AndroidRuntime(6453): FATAL EXCEPTION: main
08-26 11:24:47.775: E/AndroidRuntime(6453): Process: com.example, PID: 6453
08-26 11:24:47.775: E/AndroidRuntime(6453): java.lang.RuntimeException: Unable to resume activity {com.example/com.example.camera.VideoGallery}: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2916)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2945)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1299)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.os.Handler.dispatchMessage(Handler.java:102)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.os.Looper.loop(Looper.java:157)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.app.ActivityThread.main(ActivityThread.java:5335)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at java.lang.reflect.Method.invokeNative(Native Method)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at java.lang.reflect.Method.invoke(Method.java:515)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at dalvik.system.NativeStart.main(Native Method)
08-26 11:24:47.775: E/AndroidRuntime(6453): Caused by: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.database.BulkCursorToCursorAdaptor.throwIfCursorIsClosed(BulkCursorToCursorAdaptor.java:64)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.database.BulkCursorToCursorAdaptor.requery(BulkCursorToCursorAdaptor.java:133)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.database.CursorWrapper.requery(CursorWrapper.java:186)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.app.Activity.performRestart(Activity.java:5434)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.app.Activity.performResume(Activity.java:5460)
08-26 11:24:47.775: E/AndroidRuntime(6453):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2906)
08-26 11:24:47.775: E/AndroidRuntime(6453):     ... 10 more

2개의 답변

0 추천
음 savaInstance , onResume과 관련된 문제 인듯한데요.

Unable to resume activity 이건 어떤 엑티비티가 제활성화 않됬다는 말이고.

아마 다른 엑티비티에 갓다 왔다던지 했을때 생겼을 것으로 보이는데요. 아무튼 해당 액티비티가 onPause됐다 돌아 온것이고. Pause 되면서 현제 액티비티의 맴버인 cursor 값이 지워졌고(close) 다시 resume 하려고 보니 cursor는 먼지 모르겟다 이런 거 같습니다.

즉 onResume에서 커서를 다시 열어줄 부분을 만드시면 해결되지 않을까 합니다.
컴러기 (22,230 포인트) 님이 2015년 8월 26일 답변
0 추천

일단 아래 코드를

protected void onStop() {
        if(mVideoCursor != null && mVideoCursor.isClosed()){
            mVideoCursor.close();
        }
        if(cursor != null && cursor.isClosed()){
            cursor.close();
        }
        super.onStop();
    }

 

다음과 같이 수정해야 될 거 같네요.

protected void onStop() {
        if(mVideoCursor != null && !mVideoCursor.isClosed()){
            mVideoCursor.close();
        }
        if(cursor != null && !cursor.isClosed()){
            cursor.close();
        }
        super.onStop();
    }

 

그리고, cursor 사용 전에 열려 있는지 검사하고 사용하시면 될 듯합니다.

안 알렸으면 다시 열어줘야 됩니다.

 

아마 커서 사용한 액티비티에서 다른 액티비티로 넘어가는 순간 커서는 close하고, 다시 되돌아 왔을 때 closed된 커서를 다시 사용하려고 해서 문제가 발생하는 듯합니다.

isul (7,920 포인트) 님이 2015년 8월 26일 답변
...