【问题标题】:Android: restart search threadAndroid:重新启动搜索线程
【发布时间】:2013-06-15 15:06:44
【问题描述】:

我有一个简单的EditText 和一个TextChangedListener 和一个ListView。

onTextChanged 方法将调用以下restartSearch 方法,因此在输入EditText 时应重新启动当前搜索线程。

search 方法只是将匹配项添加到ListView。

当searchThread 仍然存在时,我想取消并重新开始搜索,这样用户界面就不会在键入时冻结,也不会花费很长时间。

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。

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

【问题讨论】:

  • 能发一下搜索方法吗?
  • 你不需要线程。发布您的搜索(查询)
  • @Raghunandan 我编辑了我的问题,我需要一个额外的线程,这样我就可以在用户输入时取消它。
  • 你根本不需要线程。重新思考你的设计。所有你需要一个自定义过滤器来搜索和更新列表视图
  • @xoxox 检查此示例stackoverflow.com/questions/10816243/…。我不使用线程

标签: java android search background-thread


【解决方案1】:

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

【讨论】:

  • 当我不在后台线程中进行搜索时,输入时 UI 不会响应。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    相关资源
    最近更新 更多