所以我有点不解。我使用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.
为什么这有时候呢?可编辑不是视图。我错过了什么?
答案 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
中执行可编辑操作。