2016-11-09 15 views
0

После того, как я разрешил пользователю загружать файлы в облако, я хочу, чтобы мое приложение перезапустило его загрузчик.onLoadFinished не всегда вызывается при перезагрузке загрузчика

Ранее onLoadFinished не всегда называют (случайным образом), когда я писал свой код следующим образом

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

Сославшись на обсуждение в Android - onLoadFinished not called, я изменить мой код

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

Это уменьшает вероятность того, что вы не позвоните onLoadFinished. Тем не менее, это будет случайным образом, если я

  1. Сделайте чистый кэш, очистите удаление в своем приложении.
  2. Установите приложение.
  3. Пробег reloadAfterOpenFromCloud. Опять же, случайным образом, onLoadFinished не будет вызываться.

Когда onLoadFinished не вызывается, если я снова запустить reloadAfterOpenFromCloud, onLoadFinished будет называться.

Я использую последние com.android.support:support-v4:25.0.0 и targetSdkVersion 25.

Мне было интересно, существует ли какое-либо реальное обходное решение, чтобы гарантировать, что onLoadFinished всегда вызывается, когда перезагружается загрузчик?

Ниже перечислены фрагменты кода.

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

Пожалуйста, добавьте полный код для класса 'HomeMenuRowInfosLoader'. Меня особенно интересует, когда вызывается 'onContentChanged()'. –

+0

@ krislarson Я обновил код. Спасибо. –

ответ

0

Вы должны реализовать какой-то наблюдатель в вашем HomeMenuRowInfosLoader, что будет вызывать onContentChanged(), когда пользователь закончит передачу облако файла.

Если onContentChanged() никогда не вызывается, takeContentChanged() всегда будут возвращать false и forceLoad() не будут вызываться в onStartLoading() после первой загрузки, при которой точка homeMenuRowInfos не равна нулем.

+0

У меня была отладка. Вызывается 'forceLoad', когда возникает проблема« onLoadFinished is not called ». –

+0

Если у вас есть 'forceLoad' для каждого' restartLoader', но не получает 'onLoadFinished', я не уверен, что это такое. В 'loadInBackground', вы всегда делаете' homeMenuRowInfos = новый ArrayList <>() 'или вы повторно используете список? Я вижу некоторый код в 'LoaderManager', который выглядит так, как будто он пропускает' onLoadFinished', если новые данные == предыдущие данные. –

 Смежные вопросы

  • Нет связанных вопросов^_^