12

I'm using Fragments and LoaderManager. I have to launch an unknown number of tasks, and they might be run in parallel (otherwise I'd just reuse one and only one loader). For example, I have a listview, and each row might have a button to save the content of that row to a webserver. The user could initiate a save request on multiple items in parallel.

private int nextId = 0;

private void onClickListener() {
    Bundle bundle = new Bundle();
    bundle.putNextData(...);
    getLoaderManager().initLoader(nextId++, bundle, this);
}

I could try bookkeeping myself, so create a pool of loaders manually and reuse them when possible, seems like it might be something already implemented by the API?

Thanks

Alex Lockwood
  • 83,063
  • 39
  • 206
  • 250
user291701
  • 38,411
  • 72
  • 187
  • 285

3 Answers3

4

I don't think you should use a Loader for saving data to a remote server.

Instead, use an IntentService or something similar to process a queue of "save" operations. This way, your communication with the web server can be batched, collapsed (i.e. multiple queued saves for a single item can be collapsed into one operation), and will live beyond the lifespan of your activity if need be.

A save queue processed by an IntentService (or equivalent) is also a great way to retry failed operations with backoff, since you can implement delayed retries with exponential backoff using AlarmManager.

Roman Nurik
  • 29,665
  • 7
  • 84
  • 82
  • And what if I have `n` categories in database and I would like to load them using `CursorLoader`. What id's should I use? – pixel Aug 20 '12 at 08:16
  • 1
    You can certainly use arbitrary IDs, and probably just integers 1..n if the categories are static. If you're first loading a list of categories and then details on each category then you probably need to optimize your query. But assuming you have no other option you should use stable ids as Loader ids, not e.g. cursor positions. – Roman Nurik Aug 20 '12 at 12:26
1

An IntentService or bound service are always good approaches for that. As Roman points, note that enqueuing several requests and called them separately is not highly recommended (it is very likely that you give a lot of work to the radio connection - when using data - which among other things drain your battery. Here is must-read about that)

I'd personally recommend to use a bound service with a queue of requests and a pool of threads available (that approach gives you full control for more complex network operations like in your case). There are more details on the approach here and a testcase working example over here.

Update us about your progress.

Jose L Ugia
  • 5,960
  • 3
  • 23
  • 26
0

You are at the right direction, let me just help you a bit.

Reusing is indeed a good idea, and you do not have to worry about it because Android did it for you(Or Java actually ;)

It called ThreadPoolExecuter, you can start as many tasks as you wish and he will only open the predefined number of threads.(Best practice is trying to open as many threads as parallel network connection can be run on the device. From my research it is between 4 - 9).

And if you are trying to download same URL twice may be you can protect your self and open only one task for it.

Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216