Android-跟踪IntentService中的多个操作

Android-跟踪IntentService中的多个操作,android,asynchronous,broadcastreceiver,Android,Asynchronous,Broadcastreceiver,我如何跟踪“N”个任务的数量-特别是当所有N个任务都已完成时,以及是否有任何任务失败 例如,我有一个服务可以响应5个独特的意图,从远程服务器下载5个独特的数据。我还需要一次下载所有5条数据。与其复制代码来下载数据,不如启动5个意图来下载所有数据,从而利用单个用例 我的问题是我需要知道5次下载尝试何时完成。我无法跟踪在该服务中进行了哪些下载,因为我使用的是IntentService。BroadcastReceive也存在同样的问题,因为它们只在onReceive方法的持续时间内存在 我正在查看se

我如何跟踪“N”个任务的数量-特别是当所有N个任务都已完成时,以及是否有任何任务失败

例如,我有一个服务可以响应5个独特的意图,从远程服务器下载5个独特的数据。我还需要一次下载所有5条数据。与其复制代码来下载数据,不如启动5个意图来下载所有数据,从而利用单个用例

我的问题是我需要知道5次下载尝试何时完成。我无法跟踪在该服务中进行了哪些下载,因为我使用的是IntentService。BroadcastReceive也存在同样的问题,因为它们只在onReceive方法的持续时间内存在

我正在查看sendOrderedBroadcast,但这需要为每次下载尝试配备一个BroadCastReceiver。我还知道,结果是在发送完成时创建的,但不是因此下载将在何时完成

“如果resultReceiver参数为非null,则指定 BroadcastReceiver的onReceive()方法将在 有序广播意图的发送完成


也许我可以尝试使用sendOrederedBroadcast并按照传递的意图打包某种计数器?

如果您想管理多个线程,使用线程池执行器可能会有所帮助


每个下载请求启动相同的服务,该服务启动一个新的异步任务,该任务在onPreExecute/onPostExecute&onCancelled中绑定和解除绑定到自身


我不知道是否可以将服务绑定到自身,如果可以的话会很有趣…

我有一个非常简洁的解决方案,似乎不会打破任何Android模式

概述 设想一个IntentService响应六个操作。其中五个操作下载一些数据,第六个操作是请求一次性下载所有数据。最初的问题是,当响应下载所有项目的操作时,如何重用逻辑来下载这五个项目。还要求在所有5次下载完成后收到通知

解决方案 当响应下载所有数据的操作时,IntentService构造一个ArrayList,其中包含与服务可以执行的每个下载操作相关的Intent字符串。IntentService通过传入要执行的下载的ArrayList来有效地调用自己。每次服务执行下载时,它都可以“弹出”ArrayList中的第一个条目,然后再次调用自己

ArrayList不必包含所有5次下载,它可以是所有可用下载的子集!每次下载尝试也可以在不中断下载“链”流或最终通知的情况下启动任何意图,传达单个成功或失败。最终,解决这个问题只需要很少的代码

protected void onHandleIntent(Intent aIntent) {
        String action = aIntent.getAction();
        // Data the service was called with.
        Bundle incomingData = aIntent.getExtras();
        // Data used to launch any new Intents.
        Bundle outgoingData = new Bundle(); 
        Intent result = null;

        if (ACTION_DOWNLOAD_ALL.equals(action)) {

              ArrayList<String> pendingDownloads = new ArrayList<String>();

              // This could contain any number of downloads, does not have to be all 5.
              pendingDownloads.add(ACTION_DOWNLOAD_1);    
              pendingDownloads.add(ACTION_DOWNLOAD_2);         
              pendingDownloads.add(ACTION_DOWNLOAD_3);
              pendingDownloads.add(ACTION_DOWNLOAD_4);
              pendingDownloads.add(ACTION_DOWNLOAD_5);

              // This will be the first download in the 'chain' to kick things off.
              result = new Intent(pendingDownloads.get(0));

              // Add the list of downloads to the Intent
              outgoingExtras.putStringArrayList("downloads", pendingDownloads);
              result.putExtras(outgoingExtras);

              // Start the download 'chain'.
              startService(result);

        } 
        else if (ACTION_DOWNLOAD_1.equals(action)) {
            // ... Do download #1.
            processDownloadChain(incomingData);
        }
        else if (ACTION_DOWNLOAD_2.equals(action)) {
            // ... Do download #2.
            processDownloadChain(incomingData);            
        }
        else if (ACTION_DOWNLOAD_3.equals(action)) {
            // ... Do download #3.
            processDownloadChain(incomingData);
        }
        else if (ACTION_DOWNLOAD_4.equals(action)) {
            // ... Do download #4.
            processDownloadChain(incomingData);
        }
        else if (ACTION_DOWNLOAD_5.equals(action)) {
            // ... Do download #5.
            processDownloadChain(incomingData);            
        }
}

private void processDownloadChain(Bundle incomingData) {

        if (incomingData != null) {

            // Get the list of downloads.
            ArrayList<String> downloads = incomingData
                    .getStringArrayList("downloads");

            if (downloads != null) {

                // Remove the handled download request from the 'chain'.
                downloads.remove(0);

                if (downloads.size() > 0) {
                    // Have another download request to handle.
                    Intent result = new Intent(downloadIntents.get(0));
                    Bundle outgoing = new Bundle();

                    outgoing.putStringArrayList("downloads", downloads);
                    result.putExtras(outgoing);
                    startService(result);
                } else {
                    // All downloads have been processed.
                    // Could notify BroadcastReceiver here.
                }
            }
        }
    }
手上受保护的无效内容(意图维护){
String action=ainent.getAction();
//调用服务时使用的数据。
Bundle incomingData=ainent.getExtras();
//用于启动任何新意图的数据。
Bundle outgoingData=新Bundle();
意图结果=空;
如果(动作\下载\全部相等(动作)){
ArrayList pendingDownloads=新建ArrayList();
//这可以包含任意数量的下载,不必全部为5。
添加(操作下载1);
添加(操作下载2);
添加(操作下载3);
添加(操作下载4);
添加(操作下载5);
//这将是“链”中的第一次下载。
结果=新意图(pendingDownloads.get(0));
//将下载列表添加到意图中
outgoingExtras.putStringArrayList(“下载”,pendingDownloads);
结果:putExtras(outgoingExtras);
//启动下载“链”。
startService(结果);
} 
else if(动作\下载\等于(动作)){
//…请下载#1。
processDownloadChain(收入数据);
}
else if(动作\下载\ 2.equals(动作)){
//…请下载#2。
processDownloadChain(收入数据);
}
else if(动作\下载\ 3.equals(动作)){
//…请下载#3。
processDownloadChain(收入数据);
}
else if(动作\下载\ 4.equals(动作)){
//…请下载#4。
processDownloadChain(收入数据);
}
else if(动作_下载_5.equals(动作)){
//…请下载#5。
processDownloadChain(收入数据);
}
}
私有void processDownloadChain(Bundle incomingData){
if(incomingData!=null){
//获取下载列表。
ArrayList下载=输入数据
.getStringArrayList(“下载”);
如果(下载!=null){
//从“链”中删除已处理的下载请求。
下载。删除(0);
如果(下载.size()>0){
//要处理另一个下载请求。
意向结果=新意向(downloadIntents.get(0));
Bundle outgoing=新Bundle();
outgoing.putStringArrayList(“下载”,下载);
结果:putExtras(传出);
startService(结果);
}否则{
//所有下载都已处理。
//能通知我吗