5

我想创建一个与此类似的服务(参考来自Here),以在 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();
}

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

这里有一些问题:

  1. 我知道这intentservice是由一些定义的动作触发的。但我想要的是创建一个后台服务来观察totalDownloadQueue,如果有任何新downloadtask的可用,那么就会调用一些线程来操作任务。

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

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

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

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

我花了 7 天时间处理复杂的需求,请大家帮忙!

4

3 回答 3

12

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

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

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

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

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

我想要的是创建一个后台服务来监视 totalDownloadQueue

我认为你不需要那个。就在您创建downloadtask呼叫服务时,您的服务将message被传递到服务类,并且您可以在该类中创建blockingqueue来处理您的消息threads

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

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

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

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

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

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

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

于 2014-09-06T21:40:16.533 回答
2

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>()
                ); 

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

tpExecutor.execute(new Runnable());
于 2014-09-06T23:28:30.453 回答
0

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

希望我能有所帮助!

于 2014-09-04T08:44:50.810 回答