Android AsyncTaskLoader doesn't start loadInBackground?

后端 未结 6 1459
有刺的猬
有刺的猬 2021-01-30 10:23

I am trying to implement a loader example on Android but can\'t get it to start the loader. I am using the following code. It will hit the \"Create Loader\" but it will never re

相关标签:
6条回答
  • 2021-01-30 10:38

    If you are using a custom loader, you can save the last data reference, and have it available via a getter. when the user rotates his screen, you can get the loader back from getLoaderManager().getLoader method, and then return back the reference. For my testing I noticed that startLoadering goes all the way to CustomLoader.onLoadFinished but the result is never deliver to activity.onLoadFinished.I suspect the activity reference gets lost upon rotation. By the way the great thing about creating loaders is they are persistent through LoaderManager. Think of it as another flavor of headless fragments.. lol.

    Loader loader  =  getLoaderManager().getLoader(LOADER_ID);
    
    if( loader == null )
    {
        getLoaderManager().initLoader(LOADER_ID, null, MyActivity.this );
    }
    else
    {
        listAdapter.addAll(((CustomLoader) loader).getLastData());
    }
    
    0 讨论(0)
  • 2021-01-30 10:39

    Since none of the answers here (besides the accepted one) alone helped me to solve this, here is how it worked for me.

    I don't think the accepted answer is the correct solution, since it causes loadInBackground() to be called more often than necessary, i.e. on orientation change, which does not happen when properly overriding the following methods in the loader as well:

    @Override
    public void deliverResult(final List<Participant> data) {
        participants = data;
    
        if (isStarted()) {
            super.deliverResult(data);
        }
    
    }
    
    @Override
    protected void onStartLoading() {
        if (takeContentChanged() || participants == null) {
            forceLoad();
        }
    }
    
    0 讨论(0)
  • 2021-01-30 10:40

    I've found that each of the above solutions have issues, especially when the app starts while the screen is turned off, and the loading takes a few moments.

    Here's my solution (base on this):

    https://stackoverflow.com/a/22675607/878126

    0 讨论(0)
  • 2021-01-30 10:41

    rrayst's advice is quite compact. If you write your method like this:

    protected void onStartLoading() {
        forceLoad();
    }
    

    you ''ll notice that when a child activity comes up and then you return to the parent one, onStartLoading (and so loadInBackground) are called again!

    What can you do? Set an internal variable (mContentChanged) to true inside the constructor; then check this variable inside onStartLoading. Only when it's true, start loading for real:

    package example.util;
    
    import android.content.Context;
    import android.support.v4.content.AsyncTaskLoader;
    
    public abstract class ATLoader<D> extends AsyncTaskLoader<D> {
    
        public ATLoader(Context context) {
            super(context);
            // run only once
            onContentChanged();
        }
    
        @Override
        protected void onStartLoading() {
            // That's how we start every AsyncTaskLoader...
            // -  code snippet from  android.content.CursorLoader  (method  onStartLoading)
            if (takeContentChanged()) {
                forceLoad();
            }
        }
    
        @Override
        protected void onStopLoading() {
            cancelLoad();
        }
    }
    
    0 讨论(0)
  • 2021-01-30 10:43

    I had the same problem using the compatibility library. I solved it by calling forceLoad

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

    Obviously the documentation on AsyncLoader is lacking and this problem also exists on HoneyComb. More information can be found here

    The official example of AsyncTaskLoader is also calling forceLoad() so its not a bug, but i still think that that behavior is not very intuitive.

    0 讨论(0)
  • 2021-01-30 10:49

    Overriding loadInBackground() is not enough.

    Have a look at the AppListLoader on http://developer.android.com/reference/android/content/AsyncTaskLoader.html .

    At least add these two methods to your loader:

            @Override
            protected void onStartLoading() {
                if (takeContentChanged())
                    forceLoad();
            }
    
            @Override
            protected void onStopLoading() {
                cancelLoad();
            }
    

    and call onContentChanged() from its constructor.

    0 讨论(0)
提交回复
热议问题