Java 异步任务';s get()方法:是否有任何情况下它实际上是最好的选择?
在回答了这个问题之后,我对使用Android的AsyncTask类的get()方法的意义/有用性产生了怀疑Java 异步任务';s get()方法:是否有任何情况下它实际上是最好的选择?,java,android,android-asynctask,Java,Android,Android Asynctask,在回答了这个问题之后,我对使用Android的AsyncTask类的get()方法的意义/有用性产生了怀疑 public final Result get () Waits if necessary for the computation to complete, and then retrieves its result. 基本上是AsyncTask类的同步解决方案,在后台操作完成之前阻止(冻结)UI 除了测试目的,甚至在那些情况下,我真的不能认为在任何情况下它实际上是一个好的解决方案,
public final Result get ()
Waits if necessary for the computation to complete, and then retrieves its result.
基本上是AsyncTask类的同步解决方案,在后台操作完成之前阻止(冻结)UI
除了测试目的,甚至在那些情况下,我真的不能认为在任何情况下它实际上是一个好的解决方案,但我可能错了,所以我感到好奇
如果需要用户实际等待AsyncTask完成,则可以显示对话框或ProgressDialog,随时控制UI。我知道这并不完全相同,但我认为这是一种比使用
get()
方法好得多的方法。在UI线程中永远不应该使用get
方法,因为它会(正如您所注意的)冻结您的UI。应该在后台线程中使用它来等待任务结束,但一般来说,尽量避免AsyncTask
)
我建议使用回调或eventbus作为替换。如果并行运行多个异步任务,您可能希望某些任务等待其他任务的结果
但是,我认为您应该避免并行运行太多异步任务,因为这会降低设备的速度。我通常使用handler类来完成这项任务(异步加载媒体)。 比如:
我发布了我自己的答案,因为这是我此刻的想法,没有人给出 我的好奇心仍然存在,所以我不会把这个标记为正确的。如果有人出色地回答了这个问题,我会认为他/她的回答是正确的 我的答案是,实际上没有使用AsyncTask的
get()
方法是最佳解决方案的场景
嗯,使用这种方法是没有意义的。我的意思是,似乎总有更好的解决办法
同样地,我会说这在语义上是令人震惊的,因为调用它会将您的AsyncTask更改为有效的“SyncTask”。如文档所示: 如有必要,等待计算完成,然后 检索其结果。“ 因此,您必须避免在UI线程上调用它,否则将得到
NetworkOnMainThreadException
。我会在涉及网络操作的测试环境中使用它,或者等待另一个任务完成
编辑:关于
networkMainThreadException
AsyncTask
不是执行后台操作的唯一方法,我错了。事实上,文档中说,AsyncTask
应该只用于最多需要几秒钟的操作。所以,如果您有需要更长时间的任务,那么应该通过实现这些任务的类对它们进行编码。其他(非AsyncTask)线程中的此类任务可能需要等待AsyncTask
完成,因此在我看来,没有人希望使用AsyncTask.get()
的情况是错误的
更新:针对一条评论,为了强调这可能是对AsyncTask.get()
的有效使用,以下情况是可能的:- 可能存在从UI线程启动的
,这可能涉及通过internet进行通信,例如加载网页或与服务器通信。无论AsyncTask
的结果是什么,都需要部分(或全部)结果来更新屏幕。因此,一个AsyncTask
及其AsyncTask
在UI线程上后跟doInBackground
是有意义的。onPostExecute
- 每当UI线程启动一个
时,它都会将AsyncTask
对象放入队列中,用于在结果可用后由单独的后台线程进行附加处理。AsyncTask
- 对于队列中的每个
,后台线程依次使用异步任务
等待任务完成,然后再执行附加处理。附加处理的一个明显例子就是将所有此类AsyncTask.get()
活动记录到internet上的服务器上,因此在后台这样做是有意义的。AsyncTask
public class MyActivity extends Activity {
static class MyAsyncTaskParameters { }
static class MyAsyncTaskResults { }
Queue<MyAsyncTask> queue; // task queue for post-processing of AsyncTasks in the background
BackgroundThread b_thread; // class related to the background thread that does the post-processing of AsyncTasks
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
queue = new ConcurrentLinkedQueue<MyAsyncTask>();
b_thread = new BackgroundThread(queue);
b_thread.Start();
}
void KickOffAsynctask(MyAsyncTaskParameters params) {
MyAsyncTask newtask = new MyAsyncTask();
newtask.execute(params);
synchronized(queue) {
queue.add(newtask);
}
}
static class MyAsyncTask extends AsyncTask<MyAsyncTaskParameters, Void, MyAsyncTaskResults> {
@Override
protected MyAsyncTaskResults doInBackground(MyAsyncTaskParameters... params) {
MyAsyncTaskResults results = new MyAsyncTaskResults();
// do AsyncTask in background
return results;
}
@Override
protected void onPostExecute(MyAsyncTaskResults res){
// take required results from MyAsyncResults for use in the user interface
}
}
static class BackgroundThread implements Runnable {
// class that controls the post processing of AsyncTask results in background
private Queue<MyAsyncTask> queue;
private Thread thisthread;
public boolean continue_running;
public BackgroundThread(Queue<MyAsyncTask> queue) {
this.queue=queue; thisthread = null; continue_running = true;
}
public void Start() {
thisthread = new Thread(this);
thisthread.start();
}
@Override
public void run() {
try {
do {
MyAsyncTask task;
synchronized(queue) {
task = queue.poll();
}
if (task == null) {
Thread.sleep(100);
} else {
MyAsyncTaskResults results = task.get();
// post processing of AsyncTask results in background, e.g. log to a server somewhere
}
} while (continue_running);
} catch(Throwable e) {
e.printStackTrace();
}
}
}
}
公共类MyActivity扩展活动{
静态类MyAsyncTaskParameters{}
静态类MyAsyncTaskResults{}
Queue Queue;//用于后台异步任务后处理的任务队列
BackgroundThread b_thread;//与执行异步任务后处理的后台线程相关的类
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
队列=新的ConcurrentLinkedQueue();
b_线程=新的背景线程(队列);
b_thread.Start();
}
无效KickOffAsynctask(MyAsyncTaskParameters参数){
MyAsyncTask newtask=新建MyAsyncTask();
newtask.execute(params);
已同步(队列){
queue.add(newtask);
}
}
静态类MyAsyncTask扩展了AsyncTask{
@凌驾
受保护的MyAsyncTaskResults doInBackground(MyAsyncTaskParameters…params){
MyAsyncTaskResults=新建MyAsyncTaskResults();
//在后台执行异步任务
返回结果;
}
@凌驾
受保护的void onPostExecute(MyAsyncTaskResults res){
//从MyAsyncResults中获取所需结果,以便在用户界面中使用
}
}
静态类BackgroundThread实现Runnable{
//类,该类控制后台异步任务结果的后处理
专用队列;
专用线程
public class MyActivity extends Activity {
static class MyAsyncTaskParameters { }
static class MyAsyncTaskResults { }
Queue<MyAsyncTask> queue; // task queue for post-processing of AsyncTasks in the background
BackgroundThread b_thread; // class related to the background thread that does the post-processing of AsyncTasks
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
queue = new ConcurrentLinkedQueue<MyAsyncTask>();
b_thread = new BackgroundThread(queue);
b_thread.Start();
}
void KickOffAsynctask(MyAsyncTaskParameters params) {
MyAsyncTask newtask = new MyAsyncTask();
newtask.execute(params);
synchronized(queue) {
queue.add(newtask);
}
}
static class MyAsyncTask extends AsyncTask<MyAsyncTaskParameters, Void, MyAsyncTaskResults> {
@Override
protected MyAsyncTaskResults doInBackground(MyAsyncTaskParameters... params) {
MyAsyncTaskResults results = new MyAsyncTaskResults();
// do AsyncTask in background
return results;
}
@Override
protected void onPostExecute(MyAsyncTaskResults res){
// take required results from MyAsyncResults for use in the user interface
}
}
static class BackgroundThread implements Runnable {
// class that controls the post processing of AsyncTask results in background
private Queue<MyAsyncTask> queue;
private Thread thisthread;
public boolean continue_running;
public BackgroundThread(Queue<MyAsyncTask> queue) {
this.queue=queue; thisthread = null; continue_running = true;
}
public void Start() {
thisthread = new Thread(this);
thisthread.start();
}
@Override
public void run() {
try {
do {
MyAsyncTask task;
synchronized(queue) {
task = queue.poll();
}
if (task == null) {
Thread.sleep(100);
} else {
MyAsyncTaskResults results = task.get();
// post processing of AsyncTask results in background, e.g. log to a server somewhere
}
} while (continue_running);
} catch(Throwable e) {
e.printStackTrace();
}
}
}
}
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
new DownloadFilesTask().get(5000, TimeUnit.MILLISECONDS);
private class Adapter extends BaseAdapter implements Filterable{
getFilter(){
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<String> suggestions = MyApiSuggestionsApi(constraint).get();
return packageAsFilterResults(suggestions);
}
}
}