9

Here nội dung này nói rằng hàm tạo API cấp 1 của SimpleCursorAdapter không còn được dùng nữa và việc sử dụng LoaderManagerCursorLoader được khuyến khích.Trình xây dựng cũ của SimpleCursorAdapter không được chấp nhận .. thực sự?

Nhưng đào sâu vào LoaderManagerCursorLoader 's sử dụng tôi thấy this ví dụ nơi bên trong một lớp bên trong mà kéo dài một ListFragment (một phần mở rộng của Fragment bản thân tôi giả sử) chúng ta tạo ra một CursorLoader. Tất cả mọi thứ có vẻ ok, ngoại trừ một thực tế là CursorLoader mất một Uri như một đối số. Vì vậy, điều này ngụ ý rằng tôi cần phải tạo một ContentProvider để có quyền truy cập vào cơ sở dữ liệu của tôi.

Tôi phải thú nhận có vẻ như quá mức cần phải trải qua tất cả điều này chỉ để tạo một đơn giản ListView với các mục đến từ cơ sở dữ liệu. Đặc biệt nếu tôi không có ý định làm cho dữ liệu cơ sở dữ liệu của tôi có sẵn cho các ứng dụng khác và mục đích chính của nhà cung cấp nội dung là thực hiện điều đó.

Vì vậy, nó thực sự đáng giá?

Đặc biệt trong các trường hợp như của tôi, nơi nội dung được tìm nạp có thể sẽ nhỏ. Tôi nghiêm túc xem xét việc làm theo cách cũ, bạn nói gì?

+1

Bạn đang hỗ trợ API 11 trở lên chỉ? – Cristian

+0

Không, tất nhiên là không, tôi đã sẵn sàng sử dụng thư viện tương thích cung cấp các phiên bản trước hỗ trợ cho Fragments and Loaders. – Bilthon

+0

tên của mẫu bạn tìm thấy (có vẻ như điều gì đó tôi muốn làm trong ứng dụng của tôi)? Liên kết chỉ giải thích các mẫu nói chung .. – Karl

Trả lời

8

Tôi đã viết một simple CursorLoader mà không cần một nhà cung cấp nội dung:

import android.content.Context; 
import android.database.Cursor; 
import android.support.v4.content.AsyncTaskLoader; 

/** 
* Used to write apps that run on platforms prior to Android 3.0. When running 
* on Android 3.0 or above, this implementation is still used; it does not try 
* to switch to the framework's implementation. See the framework SDK 
* documentation for a class overview. 
* 
* This was based on the CursorLoader class 
*/ 
public abstract class SimpleCursorLoader extends AsyncTaskLoader<Cursor> { 
    private Cursor mCursor; 

    public SimpleCursorLoader(Context context) { 
     super(context); 
    } 

    /* Runs on a worker thread */ 
    @Override 
    public abstract Cursor loadInBackground(); 

    /* Runs on the UI thread */ 
    @Override 
    public void deliverResult(Cursor cursor) { 
     if (isReset()) { 
      // An async query came in while the loader is stopped 
      if (cursor != null) { 
       cursor.close(); 
      } 
      return; 
     } 
     Cursor oldCursor = mCursor; 
     mCursor = cursor; 

     if (isStarted()) { 
      super.deliverResult(cursor); 
     } 

     if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) { 
      oldCursor.close(); 
     } 
    } 

    /** 
    * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks 
    * will be called on the UI thread. If a previous load has been completed and is still valid 
    * the result may be passed to the callbacks immediately. 
    * <p/> 
    * Must be called from the UI thread 
    */ 
    @Override 
    protected void onStartLoading() { 
     if (mCursor != null) { 
      deliverResult(mCursor); 
     } 
     if (takeContentChanged() || mCursor == null) { 
      forceLoad(); 
     } 
    } 

    /** 
    * Must be called from the UI thread 
    */ 
    @Override 
    protected void onStopLoading() { 
     // Attempt to cancel the current load task if possible. 
     cancelLoad(); 
    } 

    @Override 
    public void onCanceled(Cursor cursor) { 
     if (cursor != null && !cursor.isClosed()) { 
      cursor.close(); 
     } 
    } 

    @Override 
    protected void onReset() { 
     super.onReset(); 

     // Ensure the loader is stopped 
     onStopLoading(); 

     if (mCursor != null && !mCursor.isClosed()) { 
      mCursor.close(); 
     } 
     mCursor = null; 
    } 
} 

Nó chỉ cần lớp AsyncTaskLoader. Hoặc là một trong Android 3.0 hoặc cao hơn hoặc gói đi kèm với gói tương thích.

+0

cảm ơn rất nhiều @Cristian – confucius

+0

Tìm thấy một mẫu mã đẹp cho SimpleCursorLoader - https://bitbucket.org/ssutee/418496_mobileapp/src/fc5ee705a2fd/demo/DotDotListDB/src/th/ac/ku/android/sutee/dotdotlist - tìm thấy nó rất hữu ích! – Shushu

4

Chỉ cần sử dụng hàm tạo bên dưới nó, cái sẽ lấy cờ. Không sử dụng FLAG_AUTO_REQUERY, chỉ cần vượt qua 0 cho các cờ.

Trừ khi bạn thực sự cần xử lý các thay đổi dữ liệu cho DB cơ bản trong khi người dùng đang xem ListView thì bạn không cần phải lo lắng về việc cần phải requery.

Nếu mặt khác, bạn muốn ListView hiển thị thay đổi đối với DB trong khi người dùng đang xem danh sách, sau đó làm theo lời khuyên của Google và sử dụng CursorLoader.

EDIT:

Kể từ khi các nhà xây dựng thứ hai là chỉ có sẵn trong API 11 bạn có thể chỉ muốn mở rộng CursorAdapter mình. Bạn khá nhiều chỉ cần thực hiện bindView và newView và bạn đã hoàn tất.

1

Chỉ sử dụng hàm tạo đơn giản không được sử dụng SimpleCursorAdapter. Loại lỗi này xuất hiện khi Tôi đang phát triển ứng dụng của mình nhưng tôi đã sử dụng nó và nó hoạt động hoàn hảo với ứng dụng của tôi. Hoặc cố gắng sử dụng hàm tạo bên dưới không được chấp nhận trong trang web dành cho nhà phát triển Android có thêm đối số, tức là đối số cờ với nó.

+0

Nhưng lưu ý rằng hàm tạo thứ hai chỉ được giới thiệu ở cấp api 11. Vì vậy, tôi sẽ phải thêm thư viện tương thích chỉ để sử dụng nó. Thêm một thư viện tĩnh cũng làm cho gói ứng dụng của tôi lớn hơn ở cuối, và nếu nó chỉ vì lợi ích của việc sử dụng constructor đó, tôi thực sự không thấy điểm của nó. – Bilthon

1

Tôi tin rằng CursorLoader hiện được dự định để sử dụng với Trình cung cấp nội dung.

Nếu bạn muốn tải trực tiếp từ cơ sở dữ liệu của mình bằng khung công tác mới; bạn có thể xem xét việc mở rộng AsyncTaskLoader và trả lại nó từ onCreateLoader thay vì sử dụng CursorLoader.

Nếu bạn đang sử dụng các phương pháp hiện có, bạn phải cẩn thận hơn về thời gian hoạt động truy vấn của bạn sẽ mất. Nếu truy vấn của bạn sẽ mất một lượng thời gian đáng chú ý, hãy xem xét sử dụng AsyncTask để tải con trỏ (và nhận thức được yêu cầu đang chạy trong chuỗi giao diện người dùng).

0

Tôi biết chủ đề này là cũ, nhưng bạn chỉ có thể thêm một tham số cuối cùng vào việc tạo đối tượng SimpleCursorAdapter. Chỉ cần thêm ", 0".

Đó là một lá cờ mà Android thích và cảnh báo biến mất.

Ví dụ:

SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.item_list_layout, cursor, fromDB(), toLayout(), 0); 
Các vấn đề liên quan