Search code examples
androidandroid-asynctaskandroid-loadermanager

Extending LoaderManager - How to implement "publishProgress"?


Imagine I have a very simple long-running task as an AsyncTaskLoader:

public class DumbLoader extends AsyncTaskLoader{
   private static final String TAG = "DumbLoader";

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

   @Override
   public List<String> loadInBackground() {
       List<String> allData = new ArrayList<>();
       List<String> someData = DummyData.getItems();

       notify(someData.size()) ;// publish amount of elements of someData

       List<String> someOtherData = DummyData.getSomeOtherItems();
       notify(someOtherData.size()); //publish amount of elements of someOtherData
       allData.addAll(someData);
       allData.addAll(someOtherData);
       return allData;
   }
}

And I have an activity implementing LoaderCallbacks:

@Override
public Loader<List<String> onCreateLoader(int i, Bundle bundle) {
     return new DumbLoader(this);
}

@Override
public void onLoadFinished(Loader<String> dummyLoader, List<String> result) {
   // do something with result
}

@Override
public void onLoaderReset(Loader<String> dummyLoader) {

}

How would you implement an AsyncTask-like publishProgress?

The whole purpose of using LoaderManager is to not have to work with references, when Context/Orientation changes - however, with publishProgress the only way I can think of is passing a Handler into my DumbLoader which then notifies me. Is this a safe way? Are there better ways?

Edit: My example might be a bit misleading. In case of having two seperate functions which both return the values of my "final" result I could easily call the AsyncTaskLoader seperately for each function. I modified it to visualize that the data "published" can be different from the final result (in this example, I would like to know the size of the data, but not the data).


Solution

  • An indeterminate ProgressBar seems to me the obvious choice, for this use case. I would instantiate it when the onCreateLoader is called and dismiss it in onLoadFinished

    however, with publishProgress the only way I can think of is passing a Handler into my DumbLoader which then notifies me. Is this a safe way? Are there better ways?

    I would use the LocalBroadcastManager. The intent will be broadcasted only within your app. In your Activity/Fragment register a BroadcastReceiver and update the progress when onReceiver is invoked. Nice thing of BroadcastReceiver is that it runs always on the ui thread