I want to create a service similar to this one, (reference from Here), to download multiple files asynchronously in Android.
public static class DownloadingService extends IntentService {
public static String PROGRESS_UPDATE_ACTION = DownloadingService.class
.getName() + ".newDownloadTask";
private ExecutorService mExec;
private CompletionService<NoResultType> mEcs;
private LocalBroadcastManager mBroadcastManager;
private List<DownloadTask> mTasks;
public DownloadingService() {
super("DownloadingService");
mExec = Executors.newFixedThreadPool( 3 ); // The reason to use multiple thread is to download files asynchronously.
mEcs = new ExecutorCompletionService<NoResultType>(mExec);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
protected void onHandleIntent(Intent intent) {
while(true)
{
if( cursor <= totalDownloadQueue.size() -1) { //totalDownloadQueue is a static ArrayList which contains numerous DownloadTask
mEcs.submit(totalDownloadQueue.get(cursor));
cursor++; // The variable cursor is also a static int variable.
}
}// continuously observing the totalDownloadQueue. If any download item is added. Then the thread are dispatched to handle that.
mExec.shutdown();
}
The user can select download items among listview
in different fragments. My strategy is that as the user select the items and press download button, these items are passed into DownloadTask
which is responsible for downloading a file. Then the download tasks are added into the totalDownloadQueue
.
Here are some questions:
I know the
intentservice
is triggered by some defined action. But what I want to is to create a background service watching thetotalDownloadQueue
, if any newdownloadtask
is availabe, then some thread are called to operate the tasks.What's the side effect if I did so for this customized
intentservice
?What alternative class should I use? Please provide
sample code
along with the explanation, thanks.As I know, the initialization of the threads is only called by once. If I start the service at the beginning of the application and the threads should be killed as the user terminate the app.(I mean when he
swipe out
the window.) Do the threads exist after the user exit the application?If this approach still can't resolve the issue about downloading files asynchronously? What other strategy should I adopt? Please provide some example code or reference so that I can modify on it.
I have spent 7 days dealing with the complex requirement, any help please!
IntenService
andAsyncTask
provide a single worker thread, therefore simultaneous download of multiple images is not possible. However, i strongly suggestThreadPoolExecutor
for your requirements. It basically creates a pool of threads which are expended/shrink based on the number of tasks you apply or number of files you want to download.THreadPoolExecutor
handles practically every aspect of threads management and its quite efficient. You create a single executor with the as in this code sample:You can submit multiple downloading task by executing runnables:
and also i think you want to download simultaneously.
i think you misused the
intentservice
.intentservice
has alooper
and ahandler
and each call to start causes to create a message for the handler. all messages are queued in thelooper queue
and are served one at a time.you should use normal service and do not use
intentservice
because you want to download simultaneously not one at a time. extend service class and inonCreate
method you can create multiple threads and each thread can take a messages fromonStartCommand
. i do not want to copy and paste the doc example because i think it is better to read all of the doc again. if you read it you can completely understand how to create service that handles multiple task simultaneously although it has created just one thread in the example.http://developer.android.com/guide/components/services.html
i think you do not need that. just when you create
downloadtask
call service, yourmessage
is delivered to service class and in that class you can createblockingqueue
to handle your messages bythreads
.yes and maybe no. it depends on the process, if the process exists yes but if the process has been destroyed no. again read
lifecycle
of process to understand what process is killed or kept by android.http://developer.android.com/guide/components/processes-and-threads.html
you can use
downloadmanager
but it downloads sequentially.http://developer.android.com/reference/android/app/DownloadManager.html
http://blog.vogella.com/2011/06/14/android-downloadmanager-example/
From the sound of it you might benefit from using the onProgressUpdate method from ASyncTask, which can keep you updated on progress. Maybe have a read through the class description -- it sounds like just what you need. It also comes with lots of sample code!
Hope I am of help!