自定义EditText中的AsyncTask

时间:2016-12-06 16:09:12

标签: android android-asynctask android-edittext

所以我有点不解。我使用TextWatcher afterTextChanged(可编辑的)方法搜索用户输入的文本,并检测他是否键入了列表中的一个单词,如果是,则将跨度添加到该位置。

当我尝试直接在afterTextChanged中实现它时,随着文本的增长,搜索它并跨越特定的单词会更难,所以我将工作移到了AsynkTask类上。这是班级:

 class SearchText extends AsyncTask<String, String, Void> {
    private String match = "(\\d )?(([\\p{Alnum}\\p{Punct}])+?) ([0-9]+?)\\b:([0-9]+?)(, ([0-9]+?))?(-([0-9]+?))?\\b";
    private Editable s;

    SearchText(Editable s) {
        this.s = s;
    }

    @Override
    protected Void doInBackground(String... params) {
        Matcher m = Pattern.compile(match).matcher(s);
        while (m.find()) {
            Reference reference = new Reference(m.group(9));
            if (booksList.contains(m.group(2)) && mListener.check(reference)) {

                BooksSpan booksSpan = new BooksSpan("1");
                try {
                    s.setSpan(booksSpan, m.start(), m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                } catch (Exception e) {
                    Log.e("error", e.getMessage());
                }
            }
        }
        return null;
    }
}

s.setSpan(booksSpan, m.start(), m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);当我打字速度非常快时,就像随机字一样,它给了我:

Only the original thread that created a view hierarchy can touch its views.

为什么这有时候呢?可编辑不是视图。我错过了什么?

1 个答案:

答案 0 :(得分:1)

我测试了以下简化代码:

class SearchText extends AsyncTask<String, String, Void> {
    private String match = "t";
    private Editable s;

    SearchText(Editable s) {
        this.s = s;
    }

    @Override
    protected Void doInBackground(String... params) {
        Matcher m = Pattern.compile(match).matcher(s);
        while (m.find()) {
            try {
                s.replace(m.start(), m.end(), "A");
            } catch (Exception e) {
                Log.e("error", e.getMessage());
            }
        }
        return null;
    }
}

如果我输入的速度非常快,则抛出异常,如您所述。 当我将代码更改为以下代码时,它可以正常工作:

 class SearchText extends AsyncTask<String, String, Map<Integer, Integer>> {
    private String match = "t";
    private Editable s;

    SearchText(Editable s) {
        this.s = s;
    }

    @Override
    protected Map<Integer, Integer> doInBackground(String... params) {
        Matcher m = Pattern.compile(match).matcher(s);
        Map<Integer, Integer> map = new HashMap<>();
        while (m.find()) {
            map.put(m.start(), m.end());
        }
        return map;
    }

    @Override
    protected void onPostExecute(Map<Integer, Integer> result) {
        for (Integer i : result.keySet()) {
            try {
                s.replace(i, result.get(i), "AAAA");
            } catch (Exception e) {
                Log.e("error", e.getMessage());
            }
        }
    }
}

因此解决方案是在onPostExecute中执行可编辑操作。