Jak możesz zapytać LoaderManager, aby sprawdzić, czy Loader jest aktualnie uruchomiony?

10
synic 2 marzec 2012, 03:33

3 odpowiedzi

Najlepsza odpowiedź

Istnieją dwie możliwe sytuacje, w których można to zrobić:

1 przypadek

Jeśli używasz jedynego programu ładującego lub masz kilka, ale nie obchodzi Cię, który z nich jest uruchomiony:

getSupportLoaderManager().hasRunningLoaders()

2. przypadek

Chcesz wiedzieć, czy jakiś konkretny Loader jest uruchomiony. Wygląda na to, że nie jest obsługiwany przez SDK, ale możesz go łatwo zaimplementować samodzielnie.

A) Po prostu dodaj 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) i użyj go (trochę podchwytliwe) :-)

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

Kluczowy powód, dla którego to tutaj opublikowałem - jest to wystarczająco trudne wywołanie ogólnej metody przed rzutowaniem Loader na SomeLoader.

Przypomnienie

Cokolwiek zrobisz, jeśli nazwiesz getSupportLoaderManager.restartLoader swoje bieżące zadanie (jeśli jest uruchomione), nie zostanie zabite. Więc następnym krokiem będzie wywołanie onCreateLoader, które utworzy nowy Loader. Oznacza to, że możesz mieć 2,3,4,5 i więcej tych samych zadań równoległych razem (jeśli nie zapobiegniesz temu w jakiś sposób), co może prowadzić do rozładowania baterii i przekroczenia obciążenia procesora/sieci.

3
Slava 3 marzec 2017, 07:29

Myślę, że Slava ma dobre rozwiązanie, ale mam poprawę w jego „podstępnej” części:

Utwórz interfejs:

public interface IRunnableLoader {
    boolean IsRunning();
}

Niech klasa SomeLoader zaimplementuje interfejs:

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;
    }
    //...
}

... i użyj go tak:

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 Rzutowanie zmiennej jest bezpieczne tylko wtedy, gdy loader nie zmienia się na inny typ w innym wątku. Jeśli w twoim programie loader może zmienić się w innym wątku, użyj jakoś słowa kluczowego synchronized.

1
ffonz 31 styczeń 2018, 22:14

Posługiwać się:

getLoaderManager().getLoader(id)

Jeśli istnieje, zwróć moduł ładujący, a następnie wywołaj isStarted(), aby sprawdzić, czy działa.

-1
Daniel De León 20 lipiec 2013, 03:55