java 如何在Android中使用intentservice同时下载多个文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25659657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 08:24:59  来源:igfitidea点击:

How to download multiple files concurrently using intentservice in Android?

javaandroidmultithreadingandroid-download-managerandroid-intentservice

提问by Alston

I want to create a service similar to this one, (reference from Here), to download multiple files asynchronously in Android.

我想创建一个与此类似的服务(参考此处),以在 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 listviewin different fragments. My strategy is that as the user select the items and press download button, these items are passed into DownloadTaskwhich is responsible for downloading a file. Then the download tasks are added into the totalDownloadQueue.

用户可以listview在不同的片段中选择下载项目。我的策略是当用户选择项目并按下下载按钮时,这些项目被传递到DownloadTask负责下载文件的。然后将下载任务添加到totalDownloadQueue.

Here are some questions:

以下是一些问题:

  1. I know the intentserviceis triggered by some defined action. But what I want to is to create a background service watching the totalDownloadQueue, if any new downloadtaskis 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 codealong with the explanation, thanks.

  2. 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 outthe window.) Do the threads exist after the user exit the application?

  3. 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.

  1. 我知道intentservice是由某些定义的操作触发的。但我想要的是创建一个后台服务来监视totalDownloadQueue,如果有新downloadtask的可用,则调用一些线程来操作任务。

    如果我为这个定制的而这样做会有intentservice什么副作用?

    我应该使用什么替代课程?请提供sample code解释,谢谢。

  2. 据我所知,线程的初始化只调用一次。如果我在应用程序开始时启动服务并且线程应该在用户终止应用程序时被终止。(我的意思是当他swipe out打开窗口时。)用户退出应用程序后线程是否存在?

  3. 如果这种方式仍然不能解决异步下载文件的问题?我应该采取什么其他策略?请提供一些示例代码或参考,以便我可以对其进行修改。

I have spent 7 days dealing with the complex requirement, any help please!

我已经花了 7 天的时间来处理复杂的需求,请帮忙!

回答by mmlooloo

to download multiple files asynchronously in Android.

在Android中异步下载多个文件。

and also i think you want to download simultaneously.

而且我认为您想同时下载。

i think you misused the intentservice. intentservicehas a looperand a handlerand each call to start causes to create a message for the handler. all messages are queued in the looper queueand are served one at a time.

我认为你误用了intentservice. intentservice有 alooper和 ahandler并且每次调用 start 都会为处理程序创建一条消息。所有消息都在队列中,looper queue并且一次提供一个。

you should use normal service and do not use intentservicebecause you want to download simultaneously not one at a time. extend service class and in onCreatemethod you can create multiple threads and each thread can take a messages from onStartCommand. 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.

您应该使用普通服务,不要使用,intentservice因为您想同时下载而不是一次下载一个。扩展服务类,在onCreate方法中你可以创建多个线程,每个线程可以从onStartCommand. 我不想复制和粘贴文档示例,因为我认为最好再次阅读所有文档。如果您阅读它,您可以完全理解如何创建同时处理多个任务的服务,尽管它在示例中只创建了一个线程。

http://developer.android.com/guide/components/services.html

http://developer.android.com/guide/components/services.html

what I want to is to create a background service watching the totalDownloadQueue

我想要的是创建一个后台服务观看 totalDownloadQueue

i think you do not need that. just when you create downloadtaskcall service, your messageis delivered to service class and in that class you can create blockingqueueto handle your messages by threads.

我认为你不需要那个。就在您创建downloadtask呼叫服务时,您message将被传送到服务类,在该类中,您可以创建blockingqueue以通过threads.

Do the threads exist after the user exit the application?

用户退出应用程序后线程是否存在?

yes and maybe no. it depends on the process, if the process exists yes but if the process has been destroyed no. again read lifecycleof process to understand what process is killed or kept by android.

是的,也许不是。这取决于进程,如果进程存在是,但如果进程已被破坏则否。再次读取lifecycle进程以了解 android 杀死或保留了哪些进程。

http://developer.android.com/guide/components/processes-and-threads.html

http://developer.android.com/guide/components/processes-and-threads.html

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.

如果这种方法仍然不能解决异步下载文件的问题?我应该采取什么其他策略?请提供一些示例代码或参考,以便我可以对其进行修改。

you can use downloadmanagerbut it downloads sequentially.

您可以使用,downloadmanager但它会按顺序下载。

http://developer.android.com/reference/android/app/DownloadManager.html

http://developer.android.com/reference/android/app/DownloadManager.html

http://blog.vogella.com/2011/06/14/android-downloadmanager-example/

http://blog.vogella.com/2011/06/14/android-downloadmanager-example/

回答by eldjon

IntenServiceand AsyncTaskprovide a single worker thread, therefore simultaneous download of multiple images is not possible. However, i strongly suggest ThreadPoolExecutorfor 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. THreadPoolExecutorhandles practically every aspect of threads management and its quite efficient. You create a single executor with the as in this code sample:

IntenServiceAsyncTask提供单个工作线程,因此无法同时下载多个图像。但是,我强烈建议ThreadPoolExecutor您满足您的要求。它基本上创建了一个线程池,这些线程池根据您应用的任务数量或要下载的文件数量进行消耗/收缩。THreadPoolExecutor处理线程管理的几乎所有方面,并且非常有效。您使用此代码示例中的 as 创建单个执行程序:

ExecutorService tpExecutor=
        new ThreadPoolExecutor(
                coreSize,      // the basic number of threads, when a task is added to the queue
                               // a new thread is created if nrOfThreads < coreSize  
                maxPoolSize,   // maximum number of threads created
                keepAliveTime,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>()
                ); 

You can submit multiple downloading task by executing runnables:

您可以通过执行 runnables 来提交多个下载任务:

tpExecutor.execute(new Runnable());

回答by Sipty

From the sound of it you might benefit from using the onProgressUpdatemethod 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!

从它的声音来看,您可能会受益于使用ASyncTaskonProgressUpdate方法,它可以让您了解进度。也许通读一下课程描述——这听起来正是你所需要的。它还附带了大量的示例代码!

Hope I am of help!

希望对我有所帮助!