我有一个简单EditText
的 aTextChangedListener
和 a ListView
。
该onTextChanged
方法将调用以下restartSearch
方法,因此在输入EditText
.
该search
方法只是将匹配项添加到ListView
.
当searchThread
它仍然存在时,我想取消并重新启动搜索,这样 UI 在键入时不会冻结,也不会花费很长时间。
Thread searchThread;
private void restartSearch(CharSequence cs){
query = cs;
if(searchThread != null && searchThread.isAlive()){
searchThread.interrupt();
}
searchThread = new Thread(new Runnable() {
public void run() {
if(!lastSearch.equals(query))
search(query);
}
});
searchThread.start();
}
我称之为的方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText etSearch = ((EditText) findViewById(R.id.etSearch));
//...
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
restartSearch(s);
}
//...
});
}
和另一个(我也从那里更新 UI):
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==1){
//...
adapter.notifyDataSetChanged();
restartSearch(lastSearch);
}
else if(msg.what==2)
adapter.notifyDataSetChanged();
super.handleMessage(msg);
}
};
消息msg
是从search
更新 UI 的方法发送的:
private void search(CharSequence s){
searchResults.clear();
if(!s.toString().equals("")){
for(int i=0; i<vocsCount; i++){
try{
getResult(i, 0, 2,s);
getResult(i, 1, 1,s);
}catch(Exception ex){}
}
Collections.sort(searchResults);
}
Message msg = handler.obtainMessage();
msg.what = 2;
handler.sendMessage(msg);
lastSearch = s;
}
因此,当它每次都创建一个新的Runnable
时,它们似乎都并行运行,因为所有搜索项都多次添加到 ListView。
我怎样才能避免这种情况?