我正在实施位置建议活动,当用户在文本视图中键入时,该活动会填充来自外部服务器的建议。每次文本视图中的文字发生变化时,我都会使用AsyncTask来获取建议。键入新字母时,我们取消已存在的任务并执行新任务。大多数情况下doInBackground会在调用execute后立即启动,但有时可能需要几秒。 (一旦doInBackground启动,性能就好了。)
设置监听器:
private void init() {
// respond to any text change
textView.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(final CharSequence s, int start, int b, int c) {
showSuggestions(s.toString());
}
});
}
在这里,我们开始一项新任务并取消之前的任务:
private void showSuggestions(String query) {
// suggestionsTask is an instance variable of the activity
if (suggestionsTask != null) {
suggestionsTask.cancel(true);
}
suggestionsTask = new AsyncTask<String, Void, List<Suggestion>>() {
@Override
protected void onPostExecute(List<Suggestion> resultList) {
// set suggestions with adapter - CHANGES STATE
}
@Override
protected List<Suggestion> doInBackground(String... query) {
// one local db call for recent searches - DOES NOT CHANGE STATE
// one network call to external server - DOES NOT CHANGE STATE
// return results
}
};
suggestionsTask.execute(query);
}
是否有更好的线程机制可供使用?你知道为什么执行和doInBackground之间有延迟吗?
答案 0 :(得分:1)
可以通过调用cancel(boolean)随时取消任务。调用此方法将导致后续调用isCancelled()返回true。调用此方法后,将在doInBackground(Object [])返回后调用onCancelled(Object)而不是onPostExecute(Object)。 为了确保尽快取消任务,您应该始终从doInBackground(Object [])定期检查isCancelled()的返回值,如果可能的话(例如在循环内)。 < / p>
所以你实际上没有取消doInBackground()步骤,除非你手动检查是否在doInBackground中定期设置isCancelled()。在大多数Android版本中,所有AsyncTasks共享一个线程,因此必须在下一个线程开始之前完成。这就是你延迟的原因,但我没有足够的信息(即你没有发布代码)来自你的doInBackground()代码来提出关于在哪里检查isCancelled()的建议。
如果由于某种原因无法取消之前的任务,您也可以尝试使用executeOnExecutor(java.util.concurrent.Executor, Object[])和THREAD_POOL_EXECUTOR并行执行AsyncTasks,因为相同的文档建议,但是你用什么“试图做到这一点似乎可能会导致一些令人沮丧的线程问题,这些问题可能比你现在所遇到的更糟糕。