2013-06-12 2 views
6

콘텐츠 공급자, 콘텐츠 확인자 및 커서 로더가 있습니다. 로더는리스트 뷰를 간접적으로 채우는 데 사용됩니다 (즉, 다른 데이터를 수집하기 위해 커서 결과를 사용해야하기 때문에 어레이 어댑터가 아닌 간단한 커서 어댑터가 아닙니다).기본 데이터가 변경 될 때 커서 로더가 새로 고침되지 않습니다.

기본 데이터를 변경할 때 onLoadFinished(Loader<Cursor>, Cursor) 콜백이 호출되지 않기 때문에 목록보기가 다시 채워지지 않습니다.

이 글을 쓰는 동안 제안 된대로이 문제에 대해 많은 질문이 있습니다. 예를 들어 CursorLoader not updating after data change

그리고 모든 질문에 두 가지 지적 : 콘텐츠 제공 업체 쿼리() 메소드에서

  • , 당신은 일품 알림에 대한 커서를 알려줄 필요가

c.setNotificationUri(getContext().getContentResolver(), uri);

  • 콘텐츠 공급자 삽입/업데이트/삭제 방법에서 n URI에서 otify : 그 일을하고 있어요

getContext().getContentResolver().notifyChange(uri, null);

.

커서가 닫히지 않았습니다.

내 콘텐츠 제공 업체는 별도의 앱으로 제공됩니다 (콘텐츠 제공 업체 앱 - 런처 기본 활동 없음). com.example.provider APK이고 com.example.app는 content : //com.example.provider/table URI 등을 통해 콘텐츠 확인자에서 호출합니다. 콘텐츠 확인자 (dbhelper)는 라이브러리 프로젝트에 있습니다. (이 방법으로 여러 프로젝트가 링크를 통해 dbhelper를 사용할 수 있으며 모든 컨텐트 프로 바이더는 단일 APK를 통해 설치됩니다)

로더 관리자에서 디버깅을 사용하도록 설정 했으므로, 데이터가 변경된 후 (즉, 로더가 다시 시작되고 이전에 비활성 상태로 표시됨) 강제로 새로 고칠 위치를 볼 수 있지만 아무 것도 말하지 않는 것은 자동으로 발생합니다.

로더가 새로 고쳐지지 않는 이유는 무엇입니까?

- 편집 -

이 로더는 생성 :

는 getfoo()를 통해 커서 로더를 반환
Log.d(TAG, "onCreateLoader ID: " + loaderID); 
// typically a switch on the loader ID, and then 
return dbHelper.getfoo() 

는 :

return new CursorLoader(context, FOO_URI, foo_Fields, foo_query, foo_argArray, foo_sort);

로더 마침 커서으로 채워 소요 테이블 (그리고 약간의 처리를한다) - 아무것도 거기에서 상상하지 마라.

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
    Log.d(TAG, "onLoadFinished id: " + loader.getId()); 
    // switch on loader ID .. 
    FillTable(cursor, (FooAdapter) foo_info.listview.getAdapter(); 

로더 재설정은 테이블을 지 웁니다.

public void onLoaderReset(Loader<Cursor> loader) { 
    Log.d(TAG, "onLoaderReset id: " + loader.getId()); 
    // normally a switch on loader ID 
    ((FooAdapter)foo_info.listview.getAdapter()).clear(); 

콘텐츠 제공자는 않는다 :

공개 커서 쿼리 (URI의 URI 문자열 [] 투영, 스트링 선택 문자열 [] selectionArgs 문자열있는 sortOrder) { 커서 커서; SQLiteQueryBuilder qb = 새 SQLiteQueryBuilder();

SQLiteDatabase db = dbHelper.getReadableDatabase(); 

    switch (sUriMatcher.match(uri)) { 
    case FOO: 
     qb.setTables(FOO); 
     qb.setProjectionMap(FooProjectionMap); 
     break; 
    default: 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 

    Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); 

    c.setNotificationUri(getContext().getContentResolver(), uri); 
    return c; 

}

그런 다음/업데이 트를 삽입은 비슷하다

public Uri insert(Uri uri, ContentValues initialValues) { 
    ContentValues values; 
    if (initialValues != null) { 
     values = new ContentValues(initialValues); 
    } else { 
     values = new ContentValues(); 
    } 

    String tableName; 
    Uri contentUri; 

    switch (sUriMatcher.match(uri)) { 
    case FOO: 
     tableName = FOOTABLE; 
     contentUri = FOO_URI; 
     break; 

    default: 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 

    SQLiteDatabase db = dbHelper.getWritableDatabase(); 
    long rowId = db.insert(tableName, null, values); 
    if (rowId > 0) { 
     Uri objUri = ContentUris.withAppendedId(contentUri, rowId); 
     getContext().getContentResolver().notifyChange(objUri, null); 
     return objUri; 
    } 

    throw new SQLException("Failed to insert row into " + uri); 
} 
+0

커서 로더와 관련된 일부 코드를 게시하면 도움이 될 수 있습니다. 주로 onCreateLoader, onLoaderReset 및 onLoadFinished 메소드. 새로 고침 할 때 ContentProvider가 notifyChange 호출에 도달한다고 가정합니다. – AfzalivE

+0

죄송합니다. 폭풍/정전 등으로 얼마 동안 저를 멀리했습니다. –

답변

2

나는 당신이 당신의 onLoadFinished 및 onLoaderReset에 swapCursor 또는 changeCursor를 호출하지 않는 것을 알 수있다. 새 커서에로드 된 데이터에 어댑터가 액세스하려면이를 수행해야합니다. 이전 커서에 대한 참조를 제거하려면이 전화, onLoaderReset에서

mAdapter.swapCursor(cursor) 

: onLoadFinished에서

, 같은 전화

mAdapter.swapCursor(null) 

을 mAdapter이 목록보기의 어댑터입니다.

더 많은 정보는 : http://developer.android.com/guide/components/loaders.html#onLoadFinished

+0

커서에없는 추가 정보 나 커서가 나오는 DB를 조회해야하기 때문에 코드에서 배열 어댑터의 첫 번째 예제를 선택했을 수도 있습니다 (예 : 다른 데이터베이스에 있음, 그래서 나는 쿼리에서 JOIN을 사용할 수 없다). 반환 된 데이터에 ** swapCursor()를 수행하는 다른 간단한 커서 어댑터 (또는 간단한 커서에서 파생 됨)가 있으며 자동 새로 고침도 수행되지 않습니다. –

+0

SimpleCursorAdapter를 사용하고 추가 정보를 찾고 있습니까? 어댑터 클래스에서 추가 검색을 수행하는 사용자 지정 어댑터를 사용하는 것이 나을 것 같아요. 나는'swapCursor()'라고 부르는 다른 것들을 봐야 할 것이지만, 다른 문제가있을 수 있기 때문에 새로 고침을하지 않는다. – AfzalivE

2

그래서, 누군가를 위해 누가 이것을보고이 문제가 있습니다

는 URI 당신이에 커서를 등록하는 것이 특정 확인을하고 있습니다에 URI 당신은 커서를 통지 같은.

필자의 경우, 기본 테이블을 수정 한 다른 코드에서 사용 된 것보다 쿼리하는 데 다른 URI를 사용하고있었습니다. 통지 작업을하기위한 쉬운 수정이 없었기 때문에 OnResume()의 로더를 솔루션으로 다시 설정했습니다.

1

이 특정 문제에 대한 직접적인 대답은 아니지만 비슷한 상황에서 다른 사람들에게 도움이 될 수 있습니다. 필자의 경우에는 조인이 있었고 프로젝션과 쿼리에서 전체 tablename.columnname을 사용했지만. 그것은 어쨌든 잘못된 ID 값을 사용하여 결국. ContentProvider 또는 SQL 구문을 확인하십시오.

관련 문제