加载器重新启动时,并不总是调用onLoadFinished

时间:2016-11-09 14:26:56

标签: android android-loadermanager asynctaskloader

我让我的用户将文件下载到云后,我希望我的应用程序重新启动其加载程序。

以前,当我以下列方式编写代码时,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将不会被调用。
  4. 如果未调用onLoadFinished,如果我再次运行reloadAfterOpenFromCloud,则会调用onLoadFinished

    我正在使用最新的com.android.support:support-v4:25.0.0targetSdkVersion 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) {
        ...
    

1 个答案:

答案 0 :(得分:0)

您需要在HomeMenuRowInfosLoader中实现某种观察者,当用户完成云文件传输时,该观察者将调用onContentChanged()

如果永远不会调用onContentChanged(),则takeContentChanged()将始终返回falseforceLoad()将在第一次加载后onStartLoading()内调用homeMenuRowInfos { {1}}不等于null。