Android:重启搜索线程

时间:2013-06-15 15:06:44

标签: java android search background-thread

我有一个简单的EditTextTextChangedListenerListView

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。

我该如何避免这种情况?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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