LoaderManager dengan banyak pemuat: cara mendapatkan cursorloader yang benar

116

Bagi saya, tidak jelas bagaimana mendapatkan kursor yang tepat jika Anda memiliki banyak Loader. Katakanlah Anda mendefinisikan dua Loader yang berbeda dengan:

getLoaderManager().initLoader(0,null,this);
getLoaderManager().initLoader(1,null,this);

lalu di onCreateLoader () Anda melakukan hal yang berbeda bergantung pada id:

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {

    if (id==0){
               CursorLoader loader = new CursorLoader(getActivity(),
            MaterialContentProvider.CONTENT_URI,null,null,null,null);
    }else{
               CursorLoader loader = new CursorLoader(getActivity(),
            CustomerContentProvider.CONTENT_URI,null,null,null,null);
            };
    return loader;
} 

sejauh ini baik. Tetapi cara mendapatkan kursor yang tepat di onLoadFinished () karena Anda tidak mendapatkan id untuk mengidentifikasi Cursor yang tepat untuk Cursoradapter yang tepat.

@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {


    mycursoradapter1.swapCursor(cursor);
    if(isResumed()){
        setListShown(true);
    }else {
        setListShownNoAnimation(true);
    }



}
//and where to get the cursor for mycursoradapter2

atau saya salah dan ini adalah cara yang salah untuk mendapatkan hasil untuk dua adaptor kursor yang berbeda dalam satu fragmen.

Kay Gladen
sumber
Ini pertanyaan yang sangat bagus! Ini ditanyakan dengan baik, dan menyentuh subjek yang cukup bernuansa. Sangat spesifik.
Kurtis Nusbaum
7
Perlu disebutkan bahwa Anda harus menggunakan kelas penangan yang terpisah setiap kali tipe pengembalian loader tidak sama di semua pemuat, karena karena penghapusan tipe umum, Java tidak mengizinkan Anda untuk mengimplementasikan antarmuka ( LoaderCallbacksdalam hal ini) dengan lebih dari satu Tipe. Ini hanya berfungsi dalam kasus Anda karena kedua kali, hasilnya adalah a Cursor.
Matthias
1
@Matias Hebat Anda menyebutkannya! Saya hanya mempertimbangkan bagaimana memiliki 2 loader dengan tipe pengembalian yang berbeda. Lalu bagaimana jika 2 loader dengan 2 tipe return berbeda? Lakukan satu tugas dengan 1 pemuat, yang lainnya dengan utas?
Robert
@Robert Tidak perlu menggunakan utas. Anda dapat menggunakan dua Loaders. Silakan buka stackoverflow.com/a/20839825/2818583
AnV

Jawaban:

119

Kelas Loader memiliki metode yang disebut getId () . Saya berharap ini mengembalikan id yang Anda kaitkan dengan loader.

Kurtis Nusbaum
sumber
Terima kasih, Kurtis! Keren! Saya akan mencobanya tetapi berharap itu akan berhasil. Saya memiliki ide yang sama tetapi tidak melihat objek loader. Lihat objek kursor sebagai gantinya ...
Kay Gladen
Ia bekerja dengan Loader.getID ()! Saya sudah dua kali memeriksa ini sekarang. Bagus!
Kay Gladen
2
Saya berpikir untuk melakukan ini dengan menggunakan kelas dalam / anonim, sehingga setiap pemuat memiliki objeknya sendiri yang mendapatkan panggilan balik.
Jords
@KurtisNusaum, mengapa itu salah? Kelas dalam akan dihancurkan bersama dengan Aktivitas luar, jadi ini seharusnya tidak mengakibatkan kebocoran memori atau apa pun. Kelas statis dengan referensi kuat ke Aktivitas secara semantik setara dengan kelas dalam (yang membuat referensi kuat implisit ke kelas luar.)
Matthias
6
@Jords Ini benar secara teknis. Saya tidak memperdebatkan itu. Tapi mengapa melakukan semua omong kosong itu ketika Anda bisa menelepon getId()?
Kurtis Nusbaum
32

Gunakan metode getId () dari Loader:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    switch (loader.getId()) {
        case 0:
            // do some stuff here
            break;
        case 1:
            // do some other stuff here
            break;
        case 2:
            // do some more stuff here
            break;
        default:
            break;
    }
}    
IgorGanapolsky
sumber
8

Jika pemuat Anda tidak memiliki kesamaan selain jenis kelas dari hasil (di sini Cursor:), Anda lebih baik membuat dua LoaderCallbackscontoh terpisah (hanya sebagai dua kelas dalam dalam Aktivitas / Fragmen Anda), masing-masing didedikasikan untuk satu perlakuan pemuat, bukan daripada mencoba mencampur apel dengan jeruk.

Dalam kasus Anda, tampaknya sumber data dan perlakuan hasil berbeda, yang mengharuskan Anda menulis kode boilerplate tambahan untuk mengidentifikasi skenario saat ini dan mengirimkannya ke blok kode yang sesuai.

BladeCoder
sumber
Saya mempunyai satu pertanyaan. Tujuan dari Activitypelaksanaan LoaderCallbacksdan melewati thisuntuk getLoaderManager().initLoader()adalah untuk memastikan bahwa LoaderManagerbertindak sebagai saluran komunikasi antara Activitydan Loadermelalui LoaderCallbacks. Bagaimana saluran komunikasi itu dibuat di sini sebagai Activitytidak menerapkan LoaderCallbacksmelainkan menciptakan kelas dalam anonim?
AnV
3
Saluran komunikasi adalah LoaderCallbacks. Tidak perlu menggunakan Activitydirinya sendiri sebagai LoaderCallbacks. Lebih mudah membuat beberapa saluran komunikasi saat Anda membutuhkannya.
BladeCoder