Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/215.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
Java 提交给执行人的未来任务不';跑不动_Java_Android_Concurrency_Futuretask - Fatal编程技术网

Java 提交给执行人的未来任务不';跑不动

Java 提交给执行人的未来任务不';跑不动,java,android,concurrency,futuretask,Java,Android,Concurrency,Futuretask,我编写了一个类,它的一系列实例打算从AsyncTask调用,它将从runReport()方法返回一个结果。它创建了一个工作线程,但由于某种原因,它不会执行可调用的call()方法。我做错了什么 //Problem: doStuff() never gets called, even though the worker thread gets created. @Override public ReportResult runReport() throws InterruptedExceptio

我编写了一个类,它的一系列实例打算从AsyncTask调用,它将从runReport()方法返回一个结果。它创建了一个工作线程,但由于某种原因,它不会执行可调用的call()方法。我做错了什么

//Problem: doStuff() never gets called, even though the worker thread gets created.

@Override
public ReportResult runReport() throws InterruptedException, ExecutionException {
    Callable<ReportResult> report = new Callable<ReportResult>() {

        @Override
        public ReportResult call() throws Exception {
            doStuff();
            ...
            return new ReportResult(varWrittenByMethod);
        }
    };
    FutureTask<ReportResult> result = new FutureTask<ReportResult>(report);

    //I tried a few of these ExecutorService factory methods, with the same result.
    //I only made my own ThreadFactory to verify the worker was created
    ExecutorService es = Executors.newSingleThreadExecutor(new ThreadFact());
    es.submit(report);

    ReportResult finalResult = result.get();
    es.shutdownNow();
    return finalResult;
}


private class ThreadFact implements ThreadFactory{

    @Override
    public Thread newThread(Runnable r) {
        Log.d(TAG, "Created worker Thread");
        return new Thread(r);
    }

}
//问题:即使创建了工作线程,也不会调用doStuff()。
@凌驾
public ReportResult runReport()引发InterruptedException、ExecutionException{
可调用报告=新的可调用(){
@凌驾
public ReportResult调用()引发异常{
doStuff();
...
返回新的ReportResult(varWrittenByMethod);
}
};
未来任务结果=新的未来任务(报告);
//我尝试了其中一些ExecutorService factory方法,得到了相同的结果。
//我只创建了自己的ThreadFactory来验证worker是否已创建
ExecutorService es=Executors.newSingleThreadExecutor(新的ThreadFact());
提交(报告);
ReportResult finalResult=result.get();
es.shutdownNow();
返回最终结果;
}
私有类ThreadFact实现ThreadFactory{
@凌驾
公共线程newThread(可运行的r){
Log.d(标记“创建的工作线程”);
返回新线程(r);
}
}
据我所知,我必须在它自己的线程中作为一个FutureTask来做这件事,因为它需要做以下事情(除了返回之外,所有这些都在doStuff()中):

  • 执行一些同步设置(AsyncTask将其从UI线程中移除)
  • 调用Looper.prepare()
  • 注册一个侦听器
  • 调用Looper.loop(),捕获侦听器在一段时间内的一些回调
  • 当我有足够的数据点时,在侦听器回调中调用Looper.myLooper().quit()
  • 返回结果

我愿意用更好的方法来做这件事。我最初让AsyncTask进行此调用,然后在其线程上运行Looper.loop(),但我无法处理这些对象的队列,因为我需要在返回结果之前从侦听器调用Looper.myLooper.quit(),它不可逆地毒害了线程的消息队列。

线程工厂不会将传递的Runnable传播到创建的线程。在ThreadFactory中,请尝试:

return new Thread(r);
此外,您应该使用submit方法返回的FutureTask,而不是显式创建的FutureTask。例如

FutureTask<ReportResult> result = es.submit(report);
ReportResult finalResult = result.get();
FutureTask result=es.提交(报告);
ReportResult finalResult=result.get();

请注意,您可能会后悔在AsyncTask中执行此级别的工作,因为AsyncTask中的线程将在活动生命周期更改期间被终止。最好在IntentService中执行异步设置。如果不需要Looper(),可以使用普通线程而不是HandlerThreads。

我确实需要Looper,因为我在doStuff()中注册接收处理程序消息的侦听器(PhoneStateListener就是其中之一)。我也不需要任务运行很长时间,只需要几秒钟,实际上我希望活动生命周期发生变化。我想,如果我以后需要一个运行时间更长的应用程序,我可以从AsyncTask以外的其他程序调用。“AsyncTask中的线程将在活动生命周期更改期间被终止”--不,它们不会。例如,运行(可能提高
sleep()
time)并旋转屏幕。由于侦听器的要求,我怀疑OP可能更适合使用带有
HandlerThread
服务。我同意
AsyncTask
可能不是正确的答案,但是
AsyncTask
线程不会因为配置更改而终止。我还完全放弃了FutureTask,并提交了可调用线程以换取未来。这似乎没有什么区别(见)