Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/223.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何将前台服务中的多个任务排队,以便它们逐个执行? 公共类CopyService扩展服务{ 私人名单任务清单; 私有异步任务文件任务; @凌驾 public void onCreate(){ super.onCreate(); taskList=newarraylist(); fileTask=新fileTaskAsync(); } @凌驾 公共int onStartCommand(Intent Intent、int标志、int startId){ 字符串filePath=intent.getStringExtra(“文件路径”); String fileType=intent.getStringExtra(“文件类型”); 字符串taskType=intent.getStringExtra(“taskType”); 字符串文件名=intent.getStringExtra(“文件名”); CustomFile CustomFile=新的CustomFile(); customFile.filePath=文件路径; customFile.fileType=文件类型; customFile.taskType=任务类型; customFile.fileName=文件名; taskList.add(自定义文件); Notification Notification=getNotification(); startForeground(787,通知); if(fileTask.getStatus()!=AsyncTask.Status.RUNNING){ CustomFile current=taskList.get(0); 任务列表。删除(当前); fileTask=新建fileTaskAsync().execute(当前); } stopSelf(); 返回开始时间不粘; } @可空 @凌驾 公共IBinder onBind(意向){ 返回null; } 私有类fileTaskAsync扩展了AsyncTask{ @凌驾 受保护的字符串doInBackground(CustomFile…customFiles){ CustomFile CustomFile=customFiles[0]; FileUtils.doFileTask(customFile.filePath、customFile.fileType、, customFile.taskType); 返回customFile.fileName; } @凌驾 受保护的void onPostExecute(字符串名称){ sendResult(姓名); 如果(!taskList.isEmpty()){ CustomFile newCurrent=taskList.get(0); 任务列表。删除(newCurrent); fileTask=newFileTaskAsync().execute(newCurrent); } } } 私有void sendResult(字符串名称){ 意向意向=新意向(“任务状态”); intent.putExtra(“任务名称”,名称); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); }_Android_Android Asynctask_Android Service_Android Intentservice - Fatal编程技术网

Android 如何将前台服务中的多个任务排队,以便它们逐个执行? 公共类CopyService扩展服务{ 私人名单任务清单; 私有异步任务文件任务; @凌驾 public void onCreate(){ super.onCreate(); taskList=newarraylist(); fileTask=新fileTaskAsync(); } @凌驾 公共int onStartCommand(Intent Intent、int标志、int startId){ 字符串filePath=intent.getStringExtra(“文件路径”); String fileType=intent.getStringExtra(“文件类型”); 字符串taskType=intent.getStringExtra(“taskType”); 字符串文件名=intent.getStringExtra(“文件名”); CustomFile CustomFile=新的CustomFile(); customFile.filePath=文件路径; customFile.fileType=文件类型; customFile.taskType=任务类型; customFile.fileName=文件名; taskList.add(自定义文件); Notification Notification=getNotification(); startForeground(787,通知); if(fileTask.getStatus()!=AsyncTask.Status.RUNNING){ CustomFile current=taskList.get(0); 任务列表。删除(当前); fileTask=新建fileTaskAsync().execute(当前); } stopSelf(); 返回开始时间不粘; } @可空 @凌驾 公共IBinder onBind(意向){ 返回null; } 私有类fileTaskAsync扩展了AsyncTask{ @凌驾 受保护的字符串doInBackground(CustomFile…customFiles){ CustomFile CustomFile=customFiles[0]; FileUtils.doFileTask(customFile.filePath、customFile.fileType、, customFile.taskType); 返回customFile.fileName; } @凌驾 受保护的void onPostExecute(字符串名称){ sendResult(姓名); 如果(!taskList.isEmpty()){ CustomFile newCurrent=taskList.get(0); 任务列表。删除(newCurrent); fileTask=newFileTaskAsync().execute(newCurrent); } } } 私有void sendResult(字符串名称){ 意向意向=新意向(“任务状态”); intent.putExtra(“任务名称”,名称); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); }

Android 如何将前台服务中的多个任务排队,以便它们逐个执行? 公共类CopyService扩展服务{ 私人名单任务清单; 私有异步任务文件任务; @凌驾 public void onCreate(){ super.onCreate(); taskList=newarraylist(); fileTask=新fileTaskAsync(); } @凌驾 公共int onStartCommand(Intent Intent、int标志、int startId){ 字符串filePath=intent.getStringExtra(“文件路径”); String fileType=intent.getStringExtra(“文件类型”); 字符串taskType=intent.getStringExtra(“taskType”); 字符串文件名=intent.getStringExtra(“文件名”); CustomFile CustomFile=新的CustomFile(); customFile.filePath=文件路径; customFile.fileType=文件类型; customFile.taskType=任务类型; customFile.fileName=文件名; taskList.add(自定义文件); Notification Notification=getNotification(); startForeground(787,通知); if(fileTask.getStatus()!=AsyncTask.Status.RUNNING){ CustomFile current=taskList.get(0); 任务列表。删除(当前); fileTask=新建fileTaskAsync().execute(当前); } stopSelf(); 返回开始时间不粘; } @可空 @凌驾 公共IBinder onBind(意向){ 返回null; } 私有类fileTaskAsync扩展了AsyncTask{ @凌驾 受保护的字符串doInBackground(CustomFile…customFiles){ CustomFile CustomFile=customFiles[0]; FileUtils.doFileTask(customFile.filePath、customFile.fileType、, customFile.taskType); 返回customFile.fileName; } @凌驾 受保护的void onPostExecute(字符串名称){ sendResult(姓名); 如果(!taskList.isEmpty()){ CustomFile newCurrent=taskList.get(0); 任务列表。删除(newCurrent); fileTask=newFileTaskAsync().execute(newCurrent); } } } 私有void sendResult(字符串名称){ 意向意向=新意向(“任务状态”); intent.putExtra(“任务名称”,名称); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); },android,android-asynctask,android-service,android-intentservice,Android,Android Asynctask,Android Service,Android Intentservice,} 我需要在一个服务中逐个执行多个任务。任务是复制或移动本地文件。假设用户正在复制一个大文件,他想复制或移动其他文件。我需要对后续任务进行排队并逐一执行 目前,我正在服务中创建一个列表并运行一个异步任务。在onPostExecute中,我检查列表中的剩余任务,然后从那里再次启动异步任务。如代码所示 但是,我担心内存泄漏。我对编程非常陌生,所以我不知道在这种情况下什么是最佳实践 我不能使用IntentService,因为我希望即使用户点击home按钮打开其他应用程序,任务也能继续。正如我在评论中所

}

我需要在一个服务中逐个执行多个任务。任务是复制或移动本地文件。假设用户正在复制一个大文件,他想复制或移动其他文件。我需要对后续任务进行排队并逐一执行

目前,我正在服务中创建一个列表并运行一个异步任务。在onPostExecute中,我检查列表中的剩余任务,然后从那里再次启动异步任务。如代码所示

但是,我担心内存泄漏。我对编程非常陌生,所以我不知道在这种情况下什么是最佳实践


我不能使用IntentService,因为我希望即使用户点击home按钮打开其他应用程序,任务也能继续。

正如我在评论中所说,我认为您的解决方案是合理的。前台
服务
对于需要立即执行的长时间运行的工作是一个很好的选择,根据您的描述,您的文件复制任务符合该标准

也就是说,我不认为
AsyncTask
适合解决您的问题。当您需要在主线程之外快速执行一些工作时,最好部署AsyncTasks,最多几百毫秒,而复制任务可能需要几秒钟

由于您有多个任务要完成,而这些任务之间并没有直接的依赖关系,因此我建议您使用线程池来执行这项工作。为此,您可以使用执行器服务:

public class CopyService extends Service {

private List<CustomFile> taskList;
private AsyncTask fileTask;

@Override
public void onCreate() {
    super.onCreate();
    taskList = new ArrayList<>();
    fileTask = new fileTaskAsync();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    String filePath = intent.getStringExtra("filePath");
    String fileType = intent.getStringExtra("fileType");
    String taskType = intent.getStringExtra("taskType");
    String fileName = intent.getStringExtra("fileName");

    CustomFile customFile = new CustomFile();
    customFile.filePath = filePath;
    customFile.fileType = fileType;
    customFile.taskType = taskType;
    customFile.fileName = fileName;
    taskList.add(customFile);

    Notification notification = getNotification();

    startForeground(787, notification);

    if (fileTask.getStatus() != AsyncTask.Status.RUNNING) {

        CustomFile current = taskList.get(0);
        taskList.remove(current);

        fileTask = new fileTaskAsync().execute(current);
    }

    stopSelf();
    return START_NOT_STICKY;
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

private class fileTaskAsync extends AsyncTask<CustomFile, Void, String> {

    @Override
    protected String doInBackground(CustomFile... customFiles) {

        CustomFile customFile = customFiles[0];

        FileUtils.doFileTask(customFile.filePath, customFile.fileType,
                customFile.taskType);

        return customFile.fileName;
    }

    @Override
    protected void onPostExecute(String name) {
        sendResult(name);

        if (!taskList.isEmpty()) {
            CustomFile newCurrent = taskList.get(0);
            taskList.remove(newCurrent);
            fileTask = new fileTaskAsync().execute(newCurrent);
        }
    }
}

private void sendResult(String name) {
    Intent intent = new Intent("taskStatus");
    intent.putExtra("taskName", name);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
公共类CopyService扩展服务{
私有最终Deque任务=新建ArrayQue();
private final Deque future=executor.submit(new Runnable()){
@凌驾
公开募捐{
final CustomFile file=tasks.poll();
//Ddo正在使用该文件。。。
LocalBroadcastManager.getInstance(CopyService.this).sendBroadcast(…);
//检查是否已执行所有任务。如果已执行,请终止服务。
if(tasks.isEmpty())stopSelf();
}
});
期货。要约(期货);
}
返回开始时间不粘;
}
@凌驾
公共空间{
super.ondestory();
//如果服务正在关闭,请清除挂起和活动工作
//你可能想考虑一下是否也要重新安排这里的工作
for(未来:未来){
如果(!future.isDone()&&!future.isCancelled()){
future.cancel(true);//可能会在此处传递“false”。立即终止工作可能会产生副作用。
} 
}
}
@可空
@凌驾
公共IBinder onBind(意向){
返回null;
}

这不会导致任何内存泄漏,因为任何挂起的工作都会随服务一起被破坏。

您在服务中做的是什么工作?你能发布到目前为止你所写的代码吗?@PPartisan我编辑了我的帖子并包含了代码。我之所以没有在前面发布代码,是因为我想知道一个通用的解决方案,而不管代码是什么。但是,我想我的问题有点不清楚。我认为你的解决方案是合理的。对于您正在做的工作(需要立即执行的长时间运行的工作),
ForegroundService
是最佳解决方案。作为
AsyncTask
的替代方案,您可以使用
ExecutorService
或(如果您不介意合并额外的库)
RxJava
。我可能会得到所有需要完成的工作并立即执行,而不是为每个操作终止/重新启动多个任务。您还可以使您的
异步任务
静态
,这样它就不会隐式引用
服务
。如果需要,请使用应用程序上下文。您能告诉我如何使用应用程序上下文吗?是getApplication()还是getApplicationContext()?将内部类设置为静态
public class CopyService extends Service {

private final Deque<CustomFile> tasks = new ArrayDeque<>();
private final Deque<Future<?>> futures = new LinkedBlockingDequeue<>();
private final ExecutorService executor = Executors.newCachedThreadPool();

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    //May as well add a factory method to your CustomFile that creates one from an Intent
    CustomFile customFile = CustomFile.fromIntent(intent);
    tasks.offer(customFile);

    //...Add any other tasks to this queue...

    Notification notification = getNotification();

    startForeground(787, notification);

    for(CustomFile file : tasks) {
       final Future<?> future = executor.submit(new Runnable() {
           @Override
           public void run() {
               final CustomFile file = tasks.poll();
               //Ddo work with the file...
               LocalBroadcastManager.getInstance(CopyService.this).sendBroadcast(...);
               //Check to see whether we've now executed all tasks. If we have, kill the Service.
               if(tasks.isEmpty()) stopSelf();
           }
       });
       futures.offer(future);
    }
    return START_NOT_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    //Clear pending and active work if the Service is being shutdown
    //You may want to think about whether you want to reschedule any work here too
    for(Future<?> future : futures) {
        if(!future.isDone() && !future.isCancelled()) {
            future.cancel(true); //May pass "false" here. Terminating work immediately may produce side effects.
        } 
    }
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}