Loader and LoaderManager - how to determine if a current Loader is active and running?
Asked Answered
D

3

10

How can you query a LoaderManager to see if a Loader is currently running?

Denudation answered 1/3, 2012 at 23:33 Comment(0)
E
3

There are two possible situations of doing it:

1st case

If you use the only Loader or you have several but you don't care which one of them is running:

getSupportLoaderManager().hasRunningLoaders()

2nd case

You want to know whether some particular Loader is running. It seems it's not supported by SDK, but you can easily implement it on your own.

a) Just add the flag

public class SomeLoader extends AsyncTaskLoader<String[]> {

    public boolean isRunning;

    @Override
    protected void onStartLoading() {
        isRunning = true;
        super.onStartLoading();
        //...
        forceLoad();
    }

    @Override
    public void deliverResult(String[] data) {
        super.deliverResult(data);
        isRunning = false;
    }
    //...
}

b) and use it (a bit tricky) :-)

SomeLoader loader = (SomeLoader) manager.<String[]>getLoader(ID);
Log.d(TAG, "isRunning: " + loader.isRunning);

The key reason I have posted it here - it's a tricky enough call of a generic method before casting a Loader to your SomeLoader.

Reminder

Whatever you do if you call getSupportLoaderManager.restartLoader your current task (if it's running) is not being killed. So the next step will be a call of onCreateLoader which will create a new Loader. So it means that you can have 2,3,4,5 and more the same tasks parallel tasks together (if you don't prevent it in some way) that can lead to a battery draining and an exceed CPU/network load.

Encampment answered 3/3, 2017 at 1:41 Comment(0)
M
1

I do think Slava has a good solution, but I have an improvement for his 'tricky' part:

Create an interface:

public interface IRunnableLoader {
    boolean IsRunning();
}

Let the SomeLoader class implement the interface:

public class SomeLoader extends AsyncTaskLoader<String[]> implements IRunnableLoader {

    private boolean isRunning;

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

    @Override
    protected void onStartLoading() {
        isRunning = true;
        super.onStartLoading();
        //...
        forceLoad();
    }

    @Override
    public void deliverResult(String[] data) {
        super.deliverResult(data);
        isRunning = false;
    }

    @Override
    public boolean IsRunning() {
        return isRunning;
    }
    //...
}

... and use it like this:

Loader<String> loader = getSupportLoaderManager().getLoader(TASK_ID);
if (loader instanceof IRunnableLoader && ((IRunnableLoader)loader).IsRunning()) {
    Log.d(TAG, "is Running");
}
else {
    Log.d(TAG, "is not Running");
}

BTW Casting a variable is only safe when the loader doesn't change to some other type in another thread. If, in your program, the loader can change in another thread then use the synchronized keyword somehow.

Masterpiece answered 31/1, 2018 at 13:26 Comment(0)
F
-1

Use:

getLoaderManager().getLoader(id)

if exist return the loader, then call isStarted() to check it's running.

Fettle answered 19/7, 2013 at 23:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.