android自动完成AsyncTask延迟

时间:2016-03-21 20:37:14

标签: android android-asynctask autocomplete

我正在实施位置建议活动,当用户在文本视图中键入时,该活动会填充来自外部服务器的建议。每次文本视图中的文字发生变化时,我都会使用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之间有延迟吗?

1 个答案:

答案 0 :(得分:1)

来自AsyncTask reference

  

可以通过调用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,因为相同的文档建议,但是你用什么“试图做到这一点似乎可能会导致一些令人沮丧的线程问题,这些问题可能比你现在所遇到的更糟糕。