1

我有一个简单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。

我怎样才能避免这种情况?

4

2 回答 2

0

我不认为你真的需要在这里创建一个线程。因为 GUI 正在侦听不同的线程,并且当它在不同线程中发生的“onTextChanged”上给出回调时。如果这些不是两个不同的线程,那么您将无法在进行搜索时保​​持 GUI 响应。

于 2013-06-15T15:14:33.490 回答
0

您正在使用Thread.interrupt(),但您是否正在查询Thread.interrupted()线程实现中的值?

您应该Thread.interrupted()在完成搜索后从您的线程返回结果之前进行检查 - 如果可能的话,在您进行搜索时甚至更好 -

于 2016-11-04T20:44:03.620 回答