1

如何停止getView調用,直到我再次調用notifyDatasetChanged()?ArrayAdapter - 如何停止getView調用?

我的問題:

我有一個文本框來過濾textchange上的適配器。如果我經常更改文本,我會得到ArrayIndexOutOfBoundsException,因爲getView當然仍在訪問適配器列表,而後續過濾操作已在運行。

所以ATM它是這樣的:在後臺

  1. 過濾器+ notifyDatasetChanged
  2. GetView多次調用
  3. 當正在處理的一個過濾器,GetView仍然被稱爲是因爲背景第一個過濾器。但是,由於列表訪問(篩選操作更改列表),GetView會得到異常。所以我想停止GetView調用,然後啓動任何給定的過濾器操作。

編輯:

我想從getview回來,如果我立刻看到過濾線程處於活動狀態的?

編輯:

確定相關的適配器代碼:

@Override 
    protected FilterResults performFiltering(CharSequence constraint) { 
     filterLock.acquireUninterruptibly(); 

     FilterResults r = new FilterResults(); 
     List<T> items = null; 
     m_Filter = constraint; 

     if (constraint == null /* TextUtils.isEmpty(constraint) */) { // AR 
     // auskommentiert 
     // da 
     // ungewünscht 
     items = m_AllItems; 
     } else { 
     items = m_FilteredItems; 
     items.clear(); 

     synchronized (SyncLock) { 
      for (T item : m_AllItems) { 
      if (DynamicArrayAdapter.this.filter(item, constraint)) { 
       items.add(item); 
      } 
      } 
     } 
     } 

     r.values = items; 
     r.count = items.size(); 

     return r; 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 

     m_Items = (List<T>) results.values; 

     notifyDataSetChanged(); 

     filterLock.release(); 
    } 

這是從過濾器擴展的過濾器。在適配器中使用m_Items和m_AllItems(第一個包含過濾器,第二個未過濾)。正如你可以看到它們在performFiltering()中沒有被修改。此外,filterLock是1號信號量,因此不會同時發生2次過濾操作。

EDIT2:

也是,在我onTextChanged我可以向你保證,我不會修改適配器有以任何方式要麼,我也不在從performFiltering()稱爲濾波器()方法

+2

您不應該試圖停止getView()調用,而應該努力實現更好的過濾系統。發佈您的過濾操作代碼。 – Luksprog 2013-03-26 20:20:41

+0

您已經使篩選操作複雜化了。由於不能同時使用'Filter'類來運行兩個過濾操作,所以鎖幾乎是無用的。唯一的同步需要在訪問數據列表時完成。另外,使列表的**副本不共享數據列表。 – Luksprog 2013-03-26 20:40:23

+0

我可以發誓我跟蹤2線程通過執行過濾那裏在一起。這就是我爲什麼這樣做的原因。任何方式不傷我猜 – cdbeelala89 2013-03-26 21:01:27

回答

0

更改爲適配器不從UI線程是什麼導致您的問題。 如果您將所有適配器修改發佈到UI線程,它將不會發生,因爲它都是一個接一個地發生。

您可以在不同的線程中執行繁重的處理,但是當您想要將更改放入適配器時,您需要使用Handler或Activity.runOnUiThread在UI線程上執行此操作。例如:

// Really heavy filtering process 

runOnUiThread(new Runnable(){ 
      public void run(){ 
       // Change items of Adapter here 
       // Now we are notifying that the data has changed. 
       mAdapter.notifyDataSetChanged(); 
      } 
    }); 

看到你的代碼後: 作爲Luksprog是說,你不應該直接從其他線程更改列表中,但使用該列表的副本。 會發生什麼是ListView接受大小爲X的列表,但您已將其更改爲Y的大小,並且ListView不知道它。 您需要在項目列表副本上完成工作,完成後,在UI線程中發佈Runnable更改適配器中的項目列表並調用notifyDataSetChanged(),這是您不會與您發生衝突ListView和你的適配器。

+0

我不改變線程中的m_Items或M_AllItems。在我的文章中看到的m_FilteredItems已經是一個新列表。 – cdbeelala89 2013-03-26 20:55:58

相關問題