0

I'm trying to download multiple files from my server to my device.

Here is what i've done:

On Activities

...
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra(DownloadService.URL, url);
startService(intent);

DownloadService class

public class DownloadService extends IntentService {
...
    @Override
    protected void onHandleIntent(final Intent intent) {
        new Thread(new Runnable() {
        @Override
        public void run() {
            // Download code...
        }
    }).start();
}

My IntentService can be launched multiple times from any Activity (for example i want to download file0, file1, ..., fileN): that's why i use a Thread inside onHandleIntent, in order to download them separately.

And here is my problem: how can i cancel / interrupt the download of a specific Thread, launched from IntentService? There is no UI update during the download, but only a Notification with a progress bar, of course updated from Thread.

A file's size can be of 1GB and i'm trying to undo this download.

EDIT 1 :

DownloadManager is very useful, i know, but my file is composed by multiple sub-files, which are created one by one by server at runtime. I've already tried this way, but this is not what i'm looking for.

JJ86
  • 5,055
  • 2
  • 35
  • 64
  • That's not an appropriate use of `IntentService`. Your `IntentService` component is destroyed once `onHandleIntent()` ends, and so you are leaking your threads. If you want a service with multiple threads, create a `Service` with multiple threads (e.g., `ThreadPoolExecutor`). – CommonsWare Jun 27 '14 at 14:52
  • If you are downloading files which size can be 1GB then you should check out the `DownloadManager` class. More info can be found here: http://developer.android.com/reference/android/app/DownloadManager.html – Paul Jun 27 '14 at 14:54
  • Well, `ThreadPoolExecutor` is part of standard Java. I have not attempted to worry about stopping a specific thread inside the pool, and so I don't know the mechanics of that, but there's a good chance you can find something searching for general Java information on `ThreadPoolExecutor` and that scenario. On the Android side, you will need to track when the right time is to stop the service (e.g., when the pool is idle), and you should consider dropping the priority of your threads (`Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);`). – CommonsWare Jun 27 '14 at 15:04
  • @CommonsWare i thought taht IntentService was better then Service, but as you can see i found a dead end. Thank you for your comments! – JJ86 Jun 27 '14 at 15:06
  • That `download code` part that you ommited is the important bit, because that's where you want to regularly check whether the download must be interrupted. That interruption signal or event might be triggered from the UI thread, or some other conponent (for instance, if one download fills up all the disk, or if the network is down), and you want your thread to be able to catch that event by monitoring it between receiving chunks of the file it is downloading. – didierc Jun 27 '14 at 15:07
  • @didierc the part ommited is not too far complicate: it contains a common code used to download data from the web, and it is not my problem. I'm only trying to track down the Thread which is executing and possibly "kill" it. – JJ86 Jun 27 '14 at 15:19
  • I understand what you want, I just gave you my opinion of how that could be done cleanly. So you have 2 problems: locating and killing. Killing seems easy: http://stackoverflow.com/questions/6186537/how-do-i-kill-an-android-thread-completely – didierc Jun 27 '14 at 15:39
  • Locating is more difficult: that code is running concurrently to many other threads, so by the time you know which thread is active, another one might have picked up the cpu. – didierc Jun 27 '14 at 15:43
  • So the easiest way is to have a map between your tasks and the threads taking care of them. – didierc Jun 27 '14 at 15:45
  • @didierc thank you for the link! That's true, understand and locating the right one to kill is another problem. I will try with a map. – JJ86 Jun 27 '14 at 15:48

1 Answers1

0

Finally i managed to solve my problem.

As suggested by @CommonsWare (thanks again!) i created a Service instead of IntentService and i manage my multiple threads with a ThreadPoolExecutor in specific class called each time by onStartCommand.

Long story short: i followed this Google guide and i got inspired by the ThreadSample project.

JJ86
  • 5,055
  • 2
  • 35
  • 64