2016-12-06 47 views
0

所以我有點困惑。我使用TextWatcher afterTextChanged(可編輯)方法來搜索用戶輸入的文本,並檢測他是否鍵入了列表中的一個單詞,如果是,則將一個跨度添加到該位置。自定義EditText中的AsyncTask

當我試圖直接在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

我不知道爲什麼這種情況只發生在有時。但是當使用AsyncTask時,你應該使用'onPostExecute()'來操作UI。 – AlbAtNf

+0

可編輯用戶界面如何? –

+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執行編輯的操作。

+0

onPostExecute在UI中運行它不是好的,因爲它會減慢當文本很大 –

+0

唯一的解決方案,我會的工作是確保異步被稱爲最大每1 500密爾1次, –

+0

我結合我們的答案,我認爲是一個很好的妥協。我在onPostExecute中運行更改,但asynk每1000 milis只調用一次,所以謝謝 –