LoaderManager'da initLoader ve restartLoader arasındaki fark


129

Aşağıdakilerin işlevleri initLoaderve restartLoaderişlevleri arasındaki farklar konusunda tamamen kayboldum LoaderManager:

  • İkisinin de imzası aynı.
  • restartLoader yoksa, bir yükleyici de oluşturur ("Bu yöneticide yeni bir yükleyici başlatır veya mevcut bir Yükleyiciyi yeniden başlatır").

İki yöntem arasında bir ilişki var mı? Aramak restartLoaderher zaman arar initLoadermı? Aramak restartLoaderzorunda kalmadan arayabilir miyim initLoader? initLoaderVerileri yenilemek için iki kez aramak güvenli mi? İkisinden birini ne zaman ve neden kullanmalıyım ?

Yanıtlar:


202

Bu soruyu cevaplamak için LoaderManagerkodun içine girmeniz gerekir . LoaderManager için dokümantasyon yeterince açık olmasa da (veya bu soru olmazdı), soyut LoaderManager'ın bir alt sınıfı olan LoaderManagerImpl dokümantasyonu çok daha aydınlatıcıdır.

initLoader

Bir Yükleyici ile belirli bir kimliği başlatmak için çağrı. Bu kimlik zaten kendisiyle ilişkilendirilmiş bir Yükleyiciye sahipse, değiştirilmeden bırakılır ve önceki geri aramalar yeni sağlananlarla değiştirilir. Kimlik için şu anda bir Yükleyici yoksa, yeni bir tane oluşturulur ve başlatılır.

Bu işlev genellikle bir bileşen başlatılırken, bağlı olduğu bir Yükleyicinin oluşturulduğundan emin olmak için kullanılmalıdır. Bu, mevcut bir Yükleyicinin verilerini zaten varsa yeniden kullanmasına izin verir, böylece örneğin bir yapılandırma değişikliğinden sonra bir Etkinlik yeniden oluşturulduğunda, yükleyicilerini yeniden oluşturması gerekmez.

restartLoader

Belirli bir kimlikle ilişkilendirilmiş Yükleyiciyi yeniden oluşturma çağrısı. Şu anda bu kimlikle ilişkili bir Yükleyici varsa, uygun şekilde iptal edilecek / durdurulacak / imha edilecektir. Verilen bağımsız değişkenlere sahip yeni bir Yükleyici oluşturulacak ve verileri mevcut olduğunda size teslim edilecektir.

[...] Bu işlevi çağırdıktan sonra, bu kimlikle ilişkilendirilmiş önceki Yükleyiciler geçersiz sayılacak ve onlardan başka veri güncellemesi almayacaksınız.

Temelde iki durum vardır:

  1. Kimliğine sahip yükleyici mevcut değil: her iki yöntem de yeni bir yükleyici oluşturacak, dolayısıyla burada hiçbir fark yok
  2. Kimliğine sahip yükleyici zaten mevcut: initLoaderyalnızca parametre olarak iletilen geri aramaların yerini alacak ancak yükleyiciyi iptal etmeyecek veya durdurmayacaktır. Bir için CursorLoaderbu, imlecin açık ve aktif kaldığı anlamına gelir ( initLoaderçağrıdan önce durum böyleyse ). Diğer yandan `restartLoader, yükleyiciyi iptal eder, durdurur ve yok eder (ve temeldeki veri kaynağını bir imleç gibi kapatır) ve yeni bir yükleyici oluşturur (bu da yeni bir imleç oluşturur ve yükleyici ise sorguyu yeniden çalıştırır). bir CursorLoader).

İşte her iki yöntem için basitleştirilmiş kod:

initLoader

LoaderInfo info = mLoaders.get(id);
if (info == null) {
    // Loader doesn't already exist -> create new one
    info = createAndInstallLoader(id, args, LoaderManager.LoaderCallbacks<Object>)callback);
} else {
   // Loader exists -> only replace callbacks   
   info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback;
}

restartLoader

LoaderInfo info = mLoaders.get(id);
if (info != null) {
    LoaderInfo inactive = mInactiveLoaders.get(id);
    if (inactive != null) {
        // does a lot of stuff to deal with already inactive loaders
    } else {
        // Keep track of the previous instance of this loader so we can destroy
        // it when the new one completes.
        info.mLoader.abandon();
        mInactiveLoaders.put(id, info);
    }
}
info = createAndInstallLoader(id, args,  (LoaderManager.LoaderCallbacks<Object>)callback);

Yükleyicinin mevcut olmaması durumunda görebileceğimiz gibi (info == null), her iki yöntem de yeni bir yükleyici oluşturacaktır (info = createAndInstallLoader (...)). Yükleyicinin zaten mevcut olması durumunda, initLoaderyalnızca geri aramaların (info.mCallbacks = ...) yerini alırken restartLoadereski yükleyiciyi devre dışı bırakır (yeni yükleyici çalışmasını tamamladığında yok edilir) ve ardından yeni bir tane oluşturur.

Böylece şimdi ne zaman initLoaderve ne zaman kullanılacağı restartLoaderve iki yönteme sahip olmanın neden mantıklı olduğu açık. initLoaderbaşlatılmış bir yükleyici olduğundan emin olmak için kullanılır. Hiçbiri yoksa yeni bir tane oluşturulur, zaten varsa yeniden kullanılır. Yeni bir yükleyiciye ihtiyacımız OLMADIĞINDA bu yöntemi her zaman kullanırız çünkü çalıştırılacak sorgu değişti (temel alınan veriler değil, bir CursorLoader için SQL deyiminde olduğu gibi gerçek sorgu), bu durumda arayacağız restartLoader.

Etkinlik / Fragman yaşam döngüsü birini kullanmak kararı veya diğer yöntemle ilgisi yoktur (ve Simon önerildiği gibi bir atışlık bayrağını kullanarak aramaların takip etmek için gerek yoktur)! Bu karar, yalnızca yeni bir yükleyiciye "ihtiyaç" temel alınarak verilir. Kullandığımız aynı sorguyu çalıştırmak istersek initLoader, farklı bir sorgu çalıştırmak istersek kullanırız restartLoader.

Her zaman kullanabilirdik restartLoaderama bu verimsiz olurdu. Bir ekran dönüşünden sonra veya kullanıcı uygulamadan uzaklaşıp daha sonra aynı Aktiviteye dönerse, genellikle aynı sorgu sonucunu göstermek restartLoaderisteriz ve böylece yükleyiciyi gereksiz yere yeniden oluşturur ve temeldeki (potansiyel olarak pahalı) sorgu sonucunu reddeder.

Yüklenen veriler ile bu verileri yüklemek için "sorgu" arasındaki farkı anlamak çok önemlidir. Siparişler için bir tabloyu sorgulayan bir CursorLoader kullandığımızı varsayalım. Bu tabloya yeni bir sıra eklenirse, CursorLoader, UI'yi yeni sıralamayı güncellemesi ve göstermesi için bilgilendirmek için onContentChanged () öğesini kullanır ( restartLoaderbu durumda kullanmaya gerek yoktur ). Yalnızca açık siparişleri görüntülemek istiyorsak yeni bir sorguya ihtiyacımız var ve bunu restartLoaderyeni sorguyu yansıtan yeni bir CursorLoader döndürmek için kullanacağız .


İki yöntem arasında bir ilişki var mı?

Yeni bir Yükleyici oluşturmak için kodu paylaşırlar, ancak bir yükleyici zaten mevcut olduğunda farklı şeyler yaparlar.

Aramak restartLoaderher zaman arar initLoadermı?

Hayır, asla yapmaz.

Aramak restartLoaderzorunda kalmadan arayabilir miyim initLoader?

Evet.

initLoaderVerileri yenilemek için iki kez aramak güvenli mi?

initLoaderİki kez aramak güvenlidir, ancak hiçbir veri yenilenmeyecektir.

İkisinden birini ne zaman kullanmalıyım ve neden ?


Yukarıdaki açıklamalarımdan sonra (umarım) bu açık olmalıdır.

Yapılandırma değişiklikleri

LoaderManager, durumunu konfigürasyon değişiklikleri (yönelim değişiklikleri dahil) boyunca korur, böylece yapmamız gereken hiçbir şey kalmadığını düşünebilirsiniz. Tekrar düşün...

Her şeyden önce, bir LoaderManager geri aramaları saklamaz, bu nedenle hiçbir şey yapmazsanız onLoadFinished(), gibi geri arama yöntemlerinize ve benzerlerine çağrı almayacaksınız ve bu büyük olasılıkla uygulamanızı bozacaktır.

Bu nedenle initLoader, geri arama yöntemlerini geri yüklemek için en azından aramalıyız (a restartLoader, elbette, mümkündür). Dokümantasyon durumları:

Arama noktasında arayan başlatılmış durumdaysa ve istenen yükleyici zaten mevcutsa ve verilerini oluşturmuşsa, geri arama onLoadFinished(Loader, D)hemen çağrılacaktır (bu işlevin içinde) [...].

Bu, initLoaderbir oryantasyon değişikliğinden sonra ararsak onLoadFinished, veriler zaten yüklendiği için hemen bir çağrı alacağımız anlamına gelir (değişiklikten önce durumun böyle olduğunu varsayarak). Bu kulağa basit gelse de aldatıcı olabilir (hepimiz Android'i sevmiyor muyuz ...).

İki durumu birbirinden ayırmalıyız:

  1. Konfigürasyon değişikliklerini yönetir: Bu, setRetainInstance (true) kullanan Parçalar için veya bildiride uygun android:configChangesetikete sahip bir Etkinlik için geçerlidir . Bu bileşenler, örneğin bir ekran rotasyonundan sonra bir onCreate çağrısı almaz, bu nedenle initLoader/restartLoaderbaşka bir geri çağrı yöntemini (örn onActivityCreated(Bundle). İçinde) çağırmayı unutmayın . Yükleyiciyi / Yükleyicileri başlatabilmek için, yükleyici kimliklerinin saklanması gerekir (örneğin bir Listede). Bileşen, yapılandırma değişiklikleri boyunca korunduğundan, yalnızca mevcut yükleyici kimlikleri üzerinden döngü oluşturabilir ve çağırabiliriz initLoader(loaderid, ...).
  2. Konfigürasyon değişikliklerini kendisi işlemez: Bu durumda, Yükleyiciler onCreate içinde başlatılabilir ancak yükleyici kimliklerini manuel olarak tutmamız gerekir, aksi takdirde gerekli initLoader / restartLoader çağrılarını yapamayız.
    outState.putIntegerArrayList(loaderIdsKey, loaderIdsArray)Kimlikler bir ArrayList içinde saklanıyorsa loaderIdsArray = savedInstanceState.getIntegerArrayList(loaderIdsKey), initLoader çağrılarını yapmadan önce onSaveInstanceState içinde bir onCreate: kimliklerini geri yükleriz.

: +1: Son bir nokta. initLoaderBir rotasyondan sonra kullanırsanız (ve tüm geri aramalar bitmişse, Yükleyici boştadır) bir onLoadFinishedgeri arama almazsınız, ancak kullanırsanız restartLoaderalırsınız?
Blundell

Yanlış. İnitLoader yöntemi, dönmeden önce onLoadFinished () yöntemini çağırır (yükleyici başlatılmışsa ve verilere sahipse). Bunu daha ayrıntılı olarak açıklamak için konfigürasyon değişiklikleri hakkında bir paragraf ekledim.
Emanuel Moecklin

6
Tabii ki, cevabınız ile @ alexlockwood'un kombinasyonu tam resmi verir. Sanırım diğerleri için cevap, Sorgunuz statikse initLoader'ı kullanın ve sorguyu değiştirmek istiyorsanız yeniden başlatın
Blundell

1
Bu onu güzel bir şekilde çağırıyor: "Sorgunuz statikse initLoader'ı kullanın ve sorguyu değiştirmek istiyorsanızLoader'ı yeniden
başlatın

1
@Mhd. Tahawi, geri aramaları değiştirmiyorsunuz, onları sadece gitmeleri gereken yere ayarlıyorsunuz. Ekran döndürüldükten sonra yeniden ayarlanmaları gerekir çünkü Android, bellek sızıntılarını önlemek için onları etrafta tutmayacaktır. Doğru şeyi yaptıkları sürece onları istediğiniz her şeye ayarlamakta özgürsünüz.
Emanuel Moecklin

46

Arayan initLoaderYükleyici zaten oluşturulduğunda (bu genellikle örneğin, yapılandırma değişikliklerinden sonra gerçekleşir) Loader en son verileri sunmak için LoaderManager söyler onLoadFinishedhemen. Yükleyici önceden oluşturulmamışsa (örneğin, etkinlik / parça ilk başlatıldığında) initLoader, LoaderManager'a onCreateLoaderyeni Yükleyiciyi oluşturmak için çağrı yapmasını söyleyen çağrı .

Çağrı restartLoader, halihazırda var olan bir Yükleyiciyi (ve bununla ilişkili mevcut verileri) yok eder ve LoaderManager'a onCreateLoaderyeni Yükleyiciyi oluşturmak ve yeni bir yük başlatmak için çağrı yapmasını söyler .


Belgeler de bu konuda oldukça açık:

  • initLoaderYükleyicinin başlatılmasını ve etkin olmasını sağlar. Yükleyici halihazırda mevcut değilse oluşturulur ve (etkinlik / parça şu anda başlatılmışsa) yükleyiciyi başlatır. Aksi takdirde, son oluşturulan yükleyici yeniden kullanılır.

  • restartLoaderBu yöneticide yeni bir Yükleyici başlatır veya mevcut bir Yükleyiciyi yeniden başlatır, geri aramaları ona kaydeder ve (etkinlik / parça şu anda başlatılmışsa) onu yüklemeye başlar. Aynı kimliğe sahip bir yükleyici daha önce başlatılmışsa, yeni yükleyici işini tamamladığında otomatik olarak yok edilir. Geri arama, eski yükleyici yok edilmeden önce teslim edilecektir.


@TomanMoney Cevabımda ne anlama geldiğini açıkladım. Hangi bölümde kafan karıştı?
Alex Lockwood

az önce doktoru yeniden yazdın. Ancak doktor, her yöntemin nerede kullanılması gerektiğine ve onu karıştırmanın neden kötü olduğuna dair hiçbir ipucu vermez. Deneyimlerime göre, sadece restartLoader'ı çağırmak ve asla initLoader'ı çağırmak iyi çalışıyor. Yani bu hala kafa karıştırıcı.
Tom anMoney

3
@TomanMoney Genellikle kullandığınız initLoader()içinde onCreate()/ onActivityCreated()etkinlik / fragmanı ilk başladığında. Bu şekilde, kullanıcı bir etkinliği ilk kez açtığında, yükleyici ilk kez oluşturulacaktır ... ancak tüm etkinliğin / parçanın yok edilmesi gereken sonraki yapılandırma değişikliklerinde, aşağıdaki çağrı initLoader()basitçe eski Loaderyerine geri dönecektir . yeni bir tane yaratmak. Genellikle sorgusunu restartLoader()değiştirmeniz gerektiğinde kullanırsınız Loader(yani filtrelenmiş / sıralı veri almak istediğinizde vb.).
Alex Lockwood

4
Aynı imzaya sahip oldukları için API'nin her iki yönteme de sahip olma kararı konusunda hala kafam karıştı. API neden her seferinde "doğru olanı" yapan tek bir startLoader () yöntemi olamaz? Sanırım pek çok insanın kafasını karıştıran kısım bu.
Tom anMoney

1
@TomanMoney Buradaki belgelerde şunlar yazmaktadır: developer.android.com/guide/components/loaders.html . "Bir yapılandırma değişikliğinden sonra yeniden oluşturulduklarında son yükleyicinin imlecine otomatik olarak yeniden bağlanırlar. Bu nedenle, verilerini yeniden sorgulamaları gerekmez."
IgorGanapolsky

16

Kısa bir süre önce birden fazla yükleyici yöneticisi ve ekran yönlendirme değişiklikleriyle ilgili bir soruna rastladım ve birçok deneme yanılma sonrasında aşağıdaki modelin hem Aktiviteler hem de Parçalarda benim için işe yaradığını söylemek isterim:

onCreate: call initLoader(s)
          set a one-shot flag
onResume: call restartLoader (or later, as applicable) if the one-shot is not set.
          unset the one-shot in either case.

(başka bir deyişle, initLoader'ın her zaman bir kez çalıştırılması ve restartLoader'ın 2. ve sonraki onResume geçişlerinde çalıştırılması için bazı işaretler ayarlayın )

Ayrıca, bir Etkinlik içindeki her yükleyiciniz için farklı kimlikler atamayı unutmayın (bu, numaralandırmanıza dikkat etmezseniz, bu etkinlik içindeki parçalarda biraz sorun olabilir)


Sadece initLoader'ı kullanmayı denedim .... etkili bir şekilde çalışmadı.

Güvenilir initLoader üzerinde onCreate boş args ile & (docs bu tamam demek) restartLoader içinde (geçerli args ile) onResume docs yanlış & .... initLoader bir nullpointer istisna atar.

Güvenilir restartLoader sadece ... için çalışır iken ancak darbeler 5. veya 6. ekran yeniden yönlendirme üzerinde.

Güvenilir initLoader içinde onResume ; yine bir süre çalışır ve sonra patlar. (özellikle "başlatılmadığında çağrılan doRetain:" ... hatası)

Aşağıdakileri denedim: (yükleyici kimliğinin kurucuya geçirildiği bir kapak sınıfından alıntı)

/**
 * start or restart the loader (why bother with 2 separate functions ?) (now I know why)
 * 
 * @param manager
 * @param args
 * @deprecated use {@link #restart(LoaderManager, Bundle)} in onResume (as appropriate) and {@link #initialise(LoaderManager, Bundle)} in onCreate 
 */
@Deprecated 
public void start(LoaderManager manager, Bundle args) {
    if (manager.getLoader(this.id) == null) {
        manager.initLoader(this.id, args, this);
    } else {
        manager.restartLoader(this.id, args, this);
    }
}

(Stack-Overflow'da bir yerde bulduğum)

Yine, bu bir süre işe yaradı ama yine de ara sıra aksaklığı attı.


Hata ayıklama sırasında anlayabildiğim kadarıyla, örnek kaydetme / geri yükleme durumuyla ilgili, initLoader (/ s) 'in bir döngüde hayatta kalacaklarsa yaşam döngüsünün onCreate kısmında çalıştırılmasını gerektiren bir şey olduğunu düşünüyorum. . ( Yanılıyor olabilirim.)

Sonuçlar başka bir yönetici veya görevden geri gelene kadar başlatılamayan Yöneticiler durumunda (yani, onCreate'de başlatılamaz ), yalnızca initLoader kullanıyorum . (Bu konuda doğru olmayabilirim ama işe yarıyor gibi görünüyor. Bu ikincil yükleyiciler anlık örnek durumunun bir parçası değiller, bu nedenle initLoader kullanmak bu durumda gerçekten doğru olabilir)

yaşam döngüsü


Diyagramlara ve belgelere baktığımda, initLoader'ın Etkinlikler için onRestart'ta onCreate & restartLoader'a girmesi gerektiğini düşünürdüm, ancak bu Fragments'ı farklı bir model kullanarak bırakıyor ve bunun gerçekten kararlı olup olmadığını araştırmak için zamanım olmadı. Aktiviteler için bu modelde başarılı olup olmadığı hakkında başka biri yorum yapabilir mi?


/ @ Simon% 100 doğru ve kabul edilen cevap bu olmalı. Cevabına tam olarak inanmadım ve birkaç saat bu işi yapmanın farklı yollarını bulmaya çalıştım. İnitLoader çağrısını onCreate'e taşıdığım anda işler çalışmaya başladı. Daha sonra onStart çağrıldığı zamanları hesaba katmak için tek atış bayrağına ihtiyacınız var ancak onCreate yok
CjS

2
"Yalnızca yeniden başlatma denendi ... bir süre çalışır, ancak 5. veya 6. ekran yeniden yönlendirmesinde patlar." Öyle mi? Sadece denedim ve ekranı yüzlerce kez döndürdüm ve patlamadım. Ne tür bir istisna alıyorsun?
Tom anMoney

-1 Bu cevabın arkasındaki araştırma çabasını takdir ediyorum ancak sonuçların çoğu yanlış.
Emanuel Moecklin

1
@IgorGanapolsky neredeyse her şey. Cevabımı okur ve anlarsanız, initLoader ve restartLoader'ın ne yaptığını ve hangisinin ne zaman kullanılacağını anlarsınız ve ayrıca Simon'ın neredeyse tüm sonuçlarının neden yanlış olduğunu da anlayacaksınız. Bir parçanın / etkinliğin yaşam döngüsü ile initLoader / restartLoader'ın ne zaman kullanılacağına karar verilmesi arasında bir bağlantı yoktur (yapılandırma değişiklikleri altında açıkladığım bir uyarı ile). Simon, deneme yanılma yoluyla, yaşam döngüsünün iki yöntemi anlamanın ipucu olduğu sonucuna varıyor, ancak bu değil.
Emanuel Moecklin

@IgorGanapolsky Kendi cevabımın reklamını yapmaya çalışmıyorum. Yalnızca diğer geliştiricilere yardım etmeye ve Simon'ın sonuçlarını kendi uygulamaları için kullanmalarını engellemeye çalışıyorum. İki yöntemin ne anlama geldiğini anladığınızda, her şey oldukça açık ve uygulanması kolay hale gelir.
Emanuel Moecklin

0

initLoaderyükleyici zaten mevcutsa aynı parametreleri yeniden kullanacaktır. Yeni parametrelerle çağırsanız bile, eski veriler zaten yüklenmişse hemen geri döner. Yükleyici ideal olarak yeni verilerin etkinliğini otomatik olarak bildirmelidir. Ekran döndürülürse, initLoaderyeniden çağrılır ve eski veriler hemen görüntülenir.

restartLoaderyeniden yüklemeyi zorlamak ve parametreleri değiştirmek istediğiniz zamanlar içindir. Yükleyicileri kullanarak bir oturum açma ekranı yapacak olsaydınız, yalnızca restartLoaderdüğmeye her tıklandığında arama yapardınız . (Yanlış kimlik bilgileri vb. Nedeniyle düğme birden çok kez tıklanabilir.) initLoaderBir oturum açma işlemi sırasında ekranın döndürülmesi durumunda, yalnızca etkinliğin kaydedilmiş örnek durumunu geri yüklerken arama yaparsınız .


-1

Yükleyici zaten mevcutsa, restartLoader eskisini durduracak / iptal edecek / yok edecek, initLoader ise verilen geri arama ile onu başlatacaktır. Bu durumlarda eski geri aramaların ne işe yaradığını bulamıyorum ama sanırım terk edilecekler.

Http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/app/LoaderManager.java üzerinden taradım ancak tam olarak ne olduğunu bulamıyorum fark, bunun dışında yöntemlerin farklı şeyler yapmasıdır. Bu nedenle, initLoader'ı ilk kez kullanın ve sonraki zamanlar için yeniden başlatın derim, ancak her birinin tam olarak ne yapacağını kesin olarak söyleyemem.


Ve initLoaderbu durumda ne yapacak ?
theomega

-1

İlk başlangıçtaki yükleyici, loadInBackground () yöntemini kullanır, ikinci başlangıçta atlanır. Yani bence daha iyi çözüm:

Loader<?> loa; 
try {
    loa = getLoaderManager().getLoader(0);
} catch (Exception e) {
    loa = null;
}
if (loa == null) {
    getLoaderManager().initLoader(0, null, this);
} else {
    loa.forceLoad();
}

////////////////////////////////////////////////// /////////////////////////

protected SimpleCursorAdapter mAdapter;

private abstract class SimpleCursorAdapterLoader 
    extends AsyncTaskLoader <Cursor> {

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

    @Override
    protected void onStartLoading() {
        if (takeContentChanged() || mAdapter.isEmpty()) {
            forceLoad();
        }
    }

    @Override
    protected void onStopLoading() {
        cancelLoad();
    }

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

Bu çözümü bulmak için çok zaman harcadım - restartLoader (...) benim durumumda düzgün çalışmadı. Tek forceLoad (), geri arama olmadan önceki yükleme iş parçacığını bitirmeye izin verir (böylece tüm db işlemlerini düzgün bir şekilde bitirmiş olursunuz) ve yeniden yeni iş parçacığı başlatır. Evet, biraz fazladan zaman gerektirir, ancak daha kararlıdır. Yalnızca son başlatılan iş parçacığı geri aramayı alacaktır. Bu nedenle, db işlemlerinizi kesintiye uğratarak testler yapmak istiyorsanız - hoş geldiniz, yeniden başlatmayı deneyin (...), aksi takdirde forceLoad (). RestartLoader (...) 'ın tek rahatlığı, yeni ilk verileri, yani parametreleri sunmaktır. Ve lütfen bu durumda uygun Fragment'in onDetach () yöntemindeki loader'ı yok etmeyi unutmayın. Ayrıca, bazı zamanlarda bir faaliyetiniz olduğunda ve şunu söyleyelim: Her biri dahil olmak üzere Loader ile 2 parça - yalnızca 2 Yükleyici Yöneticisine ulaşacaksınız, bu nedenle Activity, LoaderManager'ını yükleme sırasında ilk olarak ekranda gösterilen Parçalarla paylaşır. LoaderManager.enableDebugLogging'i (true) deneyin; her bir durumda ayrıntıları görmek için.


2
-1 aramayı getLoader(0)bir try { ... } catch (Exception e) { ... }.
Alex Lockwood 13
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.