2013-06-12 27 views
6

Tôi có nhà cung cấp nội dung, trình phân giải nội dung và trình tải con trỏ. Trình tải được sử dụng để điền một listview gián tiếp (tức là không phải là một bộ chuyển đổi con trỏ đơn giản, thay vì một bộ điều hợp mảng, vì tôi cần sử dụng các kết quả của con trỏ để thu thập dữ liệu khác).Trình tải con trỏ không làm mới khi thay đổi dữ liệu cơ bản

Khi tôi thay đổi dữ liệu cơ bản, chế độ xem danh sách không được điền lại vì không gọi lại số gọi onLoadFinished(Loader<Cursor>, Cursor).

Như đã đề xuất trong khi tôi viết bài này, có rất nhiều câu hỏi về vấn đề này. ví dụ CursorLoader not updating after data change

Và tất cả những câu hỏi chỉ ra hai điều:

  • Trong cung cấp nội dung truy vấn của bạn() phương pháp, bạn cần phải nói với con trỏ về thông báo A'la

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

  • Trong phương pháp chèn/cập nhật/xóa nhà cung cấp nội dung của bạn, bạn cần phải n otify trên URI:

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

tôi đang làm những điều đó.

Tôi cũng KHÔNG đóng bất kỳ con trỏ nào mà tôi quay lại.

Lưu ý, nhà cung cấp nội dung của tôi sống trong một ứng dụng riêng biệt (coi ứng dụng này là ứng dụng của nhà cung cấp nội dung - không có hoạt động chính của trình khởi chạy). APK com.example.provider và com.example.app đang gọi (trong trình phân giải nội dung) thông qua nội dung: //com.example.provider/table URI, vv. Trình giải quyết nội dung (dbhelper) nằm trong dự án thư viện (com.example.appdb) mà hoạt động liên kết. (Bằng cách này, nhiều dự án có thể sử dụng dbhelper thông qua liên kết và tất cả các nhà cung cấp nội dung được cài đặt qua một APK)

Tôi đã bật gỡ lỗi trong trình quản lý bộ nạp, và có thể thấy nơi tôi buộc làm mới sau khi thay đổi dữ liệu (nghĩa là trình tải đang được khởi động lại và trước đó được đánh dấu là không hoạt động), nhưng không có gì cho biết bất kỳ điều gì đang diễn ra tự động - thay vào đó, để làm mới lực của tôi.

Bất kỳ ý tưởng nào khiến trình tải của tôi không được làm mới?

- EDIT -

Bộ nạp tạo:

Log.d(TAG, "onCreateLoader ID: " + loaderID); 
// typically a switch on the loader ID, and then 
return dbHelper.getfoo() 

đâu getFoo() trả về một con trỏ nạp qua:

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

Loader Kết thúc mất con trỏ và populates một bảng (và không xử lý một số) - không có gì lạ mắt ở đó.

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(); 

Đặt lại bộ nạp xóa bảng.

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(); 

Các nhà cung cấp nội dung thực hiện:

truy vấn Cursor công cộng (Uri uri, String [] chiếu, String lựa chọn, String [] selectionArgs, String sortOrder) { Cursor con trỏ; SQLiteQueryBuilder qb = new 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; 

}

Sau đó chèn/cập nhật cũng tương tự như:

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

Đăng một số mã của bạn liên quan đến Trình tải con trỏ có thể hữu ích. Chủ yếu là các phương thức onCreateLoader, onLoaderReset và onLoadFinished của bạn. Tôi giả định ContentProvider của bạn đến cuộc gọi notifyChange khi bạn làm mới. – AfzalivE

+0

Xin lỗi, bão/cúp điện đã khiến tôi mất một thời gian. –

Trả lời

2

tôi thấy rằng bạn đang không gọi swapCursor hoặc changeCursor trong onLoadFinished và onLoaderReset của bạn. Bạn cần làm điều đó để bộ điều hợp truy cập dữ liệu được nạp vào con trỏ mới.

trong onLoadFinished, gọi cái gì đó như:

mAdapter.swapCursor(cursor) 

Trong onLoaderReset, gọi đây là để loại bỏ các tham chiếu tới con trỏ cũ:

mAdapter.swapCursor(null) 

đâu mAdapter là bộ chuyển đổi của ListView của bạn. Thông tin

thêm: http://developer.android.com/guide/components/loaders.html#onLoadFinished

+0

Tôi có thể đã chọn ví dụ đầu tiên trong mã của tôi, một trong đó là bộ điều hợp mảng, vì chúng tôi cần tra cứu thông tin bổ sung không có trong con trỏ, hoặc trong DB con trỏ đến (tức là nó nằm trong cơ sở dữ liệu khác, vì vậy tôi không thể sử dụng JOIN trong truy vấn). Có một số simplecursoradapter khác (hoặc bắt nguồn từ con trỏ đơn giản) mà ** do ** 'swapCursor()' trên dữ liệu trả về (và cũng không tự động làm mới). –

+0

Bạn đang sử dụng SimpleCursorAdapter và sau đó tìm kiếm thông tin bổ sung? Dường như với tôi bạn có thể tốt hơn bằng cách sử dụng một bộ điều hợp tùy chỉnh mà hiện tra cứu bổ sung đó trong lớp bộ điều hợp. Tôi sẽ phải nhìn vào những cái khác gọi là 'swapCursor()' nhưng không được làm mới vì chúng có thể có một số vấn đề khác. – AfzalivE

2

Vì vậy, đối với bất cứ ai trông này lên và có vấn đề này:

Hãy chắc chắn rằng URI bạn đăng ký con trỏ trên, và URI bạn thông báo cho con trỏ trên là tương tự.

Trong trường hợp của tôi, tôi đã sử dụng một URI khác để truy vấn so với được sử dụng trong mã khác đã sửa đổi bảng bên dưới. Không có cách khắc phục dễ dàng để thực hiện công việc thông báo, vì vậy tôi đã đặt lại trình tải trong OnResume() làm giải pháp.

1

Đây không phải là câu trả lời trực tiếp cho vấn đề cụ thể này, nhưng có thể giúp những người khác trong một tình huống tương tự. Trong trường hợp của tôi, tôi đã tham gia và mặc dù tôi đã sử dụng tablename.columnname đầy đủ trong phép chiếu và truy vấn. Nó đã kết thúc bằng cách sử dụng các giá trị ID sai anyway. Vì vậy, hãy chắc chắn kiểm tra cú pháp ContentProvider hoặc SQL của bạn.

Các vấn đề liên quan