2016-11-09 6 views
0

Nachdem ich meinen Benutzer Dateien in die Cloud herunterladen lasse, möchte ich, dass meine App den Loader neu startet.onLoadFinished wird nicht immer aufgerufen, wenn der Loader neu gestartet wird

Zuvor wird onLoadFinished nicht immer (zufällig) genannt zu werden, wenn ich meinen Code auf folgende Weise in Android - onLoadFinished not called

public void reloadAfterOpenFromCloud() { 
    LoaderManager loaderManager = this.getLoaderManager(); 
    loaderManager.restartLoader(0, bundle, this); 
} 

Nach einem Hinweis auf die Diskussion schrieb ich meinen Code zu

public void reloadAfterOpenFromCloud() { 
    // https://stackoverflow.com/questions/16014992/android-onloadfinished-not-called 
    // This seems to be a realiable way, to make sure onCreateLoader and onLoadFinished will 
    // be called. 
    LoaderManager loaderManager = this.getLoaderManager(); 
    Loader loader = loaderManager.getLoader(0); 
    if (loader != null) { 
     loaderManager.destroyLoader(0); 
    } 
    loaderManager.restartLoader(0, bundle, this); 
} 
ändern

Dies verringert die Wahrscheinlichkeit, nicht onLoadFinished aufzurufen. Allerdings wird es immer noch zufällig passieren, wenn ich

  1. Löschen Sie einen Cache, saubere Deinstallation auf meiner App.
  2. Installieren Sie die App.
  3. Führen Sie reloadAfterOpenFromCloud. Wieder zufällig wird onLoadFinished nicht aufgerufen.

Wenn onLoadFinished nicht aufgerufen wird, wenn ich reloadAfterOpenFromCloud erneut ausführen, werden onLoadFinished aufgerufen werden.

Ich verwende neueste com.android.support:support-v4:25.0.0 und targetSdkVersion 25.

Ich frage mich, gibt es eine echte Workaround, um sicherzustellen, onLoadFinished wird immer aufgerufen, wenn der Lader neu gestartet?


Die folgenden Teile sind Teil meiner Code-Schnipsel.

public void reloadAfterOpenFromCloud() { 
    // https://stackoverflow.com/questions/16014992/android-onloadfinished-not-called 
    // This seems to be a realiable way, to make sure onCreateLoader and onLoadFinished will 
    // be called. 
    LoaderManager loaderManager = this.getLoaderManager(); 
    Loader loader = loaderManager.getLoader(0); 
    if (loader != null) { 
     loaderManager.destroyLoader(0); 
    } 
    loaderManager.restartLoader(0, bundle, this); 
} 

static class HomeMenuRowInfosLoader extends AsyncTaskLoader<List<HomeMenuRowInfo>> { 

    private List<HomeMenuRowInfo> homeMenuRowInfos = null; 

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

    @Override 
    public List<HomeMenuRowInfo> loadInBackground() { 
     ... 
     return homeMenuRowInfos; 
    } 

    /** 
    * Handles a request to cancel a load. 
    */ 
    @Override 
    public void onCanceled(List<HomeMenuRowInfo> homeMenuRowInfos) { 
     super.onCanceled(homeMenuRowInfos); 
    } 

    /** 
    * Handles a request to stop the Loader. 
    * Automatically called by LoaderManager via stopLoading. 
    */ 
    @Override 
    protected void onStopLoading() { 
     // Attempt to cancel the current load task if possible. 
     cancelLoad(); 
    } 

    /** 
    * Handles a request to start the Loader. 
    * Automatically called by LoaderManager via startLoading. 
    */ 
    @Override   
    protected void onStartLoading() { 
     if (this.homeMenuRowInfos != null) { 
      deliverResult(this.homeMenuRowInfos); 
     } 

     if (takeContentChanged() || this.homeMenuRowInfos == null) { 
      forceLoad(); 
     } 
    } 

    /** 
    * Handles a request to completely reset the Loader. 
    * Automatically called by LoaderManager via reset. 
    */ 
    @Override 
    protected void onReset() { 
     super.onReset(); 

     // Ensure the loader is stopped 
     onStopLoading(); 

     // At this point we can release the resources associated with 'apps' 
     // if needed. 
     this.homeMenuRowInfos = null; 
    }   
} 

@Override 
public Loader<List<HomeMenuRowInfo>> onCreateLoader(int arg0, Bundle bundle) { 
    return new HomeMenuRowInfosLoader(this.getActivity()); 
} 

// Not being called always when restart loader 
@Override 
public void onLoadFinished(Loader<List<HomeMenuRowInfo>> arg0, List<HomeMenuRowInfo> homeMenuRowInfos) { 
    ... 
+0

Bitte fügen Sie den vollständigen Code für Ihre 'HomeMenuRowInfosLoader' Klasse hinzu. Ich bin speziell daran interessiert, wann 'onContentChanged()' aufgerufen wird. –

+0

@krislarson Ich habe den Code aktualisiert. Vielen Dank. –

Antwort

0

Sie benötigen eine Art Beobachter in Ihrem HomeMenuRowInfosLoader zu implementieren, die onContentChanged() aufrufen, wenn der Benutzer die Cloud-File-Transfer abgeschlossen ist.

Wenn onContentChanged() nie aufgerufen wird, wird takeContentChanged() immer false zurückkehren und forceLoad() nicht innerhalb onStartLoading() nach der ersten Belastung genannt werden, an welchem ​​Punkt homeMenuRowInfos nicht gleich null.

+0

Ich hatte Debuggen. 'forceLoad' wird aufgerufen, wenn das Problem" onLoadFinished wird nicht aufgerufen "auftritt. –

+0

Wenn Sie für jeden 'restartLoader' einen passenden' forceLoad' haben, aber nicht 'onLoadFinished', dann bin ich mir nicht sicher, was das ist. Machen Sie in 'loadInBackground' immer' homeMenuRowInfos = new ArrayList <>() 'oder verwenden Sie die Liste erneut? Ich sehe Code in 'LoaderManager', der aussieht, als würde er' onLoadFinished' überspringen, wenn die neuen Daten == vorherige Daten. –

Verwandte Themen