“实时”使用 AsyncTask 进行搜索?

发布于 2024-10-04 21:45:10 字数 432 浏览 1 评论 0原文

我正在编写一个“实时”搜索数据库的应用程序。 即,当用户按下字母时,它会更新搜索结果列表。

由于搜索可能需要一段时间,因此我需要在后台进行搜索并允许按新按键重新开始搜索。因此,用户按下“a”(代码开始搜索“a”),然后按下“b”——代码不会等待“a”搜索结束,然后开始搜索“ab”,而是停止“a”搜索,并开始新的“ab”搜索。

  • 为此,我决定在 AsyncTask 中进行搜索。这是一个明智的决定吗?

现在 - 每当检测到按键时,我都会测试是否有 AsyncTask 正在运行。如果我这样做 - 我向它发出信号(在 AsyncTask 中使用布尔值)它应该停止。然后设置一个计时器,在 10 毫秒内重新测试 AsyncTask,看看它是否终止,并开始新的搜索。

  • 这是一个聪明的方法吗?或者您会采取另一种方法吗?

TIA

I am writing an application that searches a database in "realtime".
i.e. as the user presses letters it updates a search results list.

Since the search can take a while, I need to do the search in background and allow new key presses to re-start a search. So that is a user presses 'a' (and the code starts searching for "a"), then presses 'b' - the code will NOT wait for "a" search to end, then start searching for "ab", but rather STOP the "a" search, and start a new "ab" search.

  • To do that I decided to do the search in an AsyncTask. Is this a wise decision ?

Now - whenever a keypress is detected, I test to see if I have an AsyncTask running. If I do - I signal it (using a boolean within the AsyncTask) it should stop. Then set a timer to re-test the AsyncTask within 10 mSec, to see if it terminated, and start the new search.

  • Is this a smart method ? Or is there another approach you would take ?

TIA

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

灯角 2024-10-11 21:45:10

首先,AsyncTask 是实现此目的的好方法。我发现你的方法的问题是计时器等待观看某些东西死亡。当您调用 asyncTask 时,请保留它的引用。让它为您保留状态,以便您知道它是否正在搜索或已返回。当用户单击另一个字母时,您可以告诉 asyncTask 取消。像这样的事情:

public void onClick() {
   if( searchTask != null ) {
      searchTask.cancel();
   }

   searchTask = new SearchTask( MyActivity.this ).execute( textInput.getText() );
}

public class SearchTask extends AsyncTask<String,Integer,List<SearchResult>> {
    private boolean canceled = false;

    protected onPostExecute( List<SearchResult> results ) {
       if( !canceled ) {
          activity.handleResults( results );
       }
    }

    public void cancel() {
       canceled = true;
    }
}

这是安全的,因为 onPostExecute() 位于 UI 线程上。而且cancel()仅从UI线程调用,因此不存在线程安全问题,也不需要同步。您不必眼睁睁地看着线程死亡。只需让 GC 处理清理工作即可。一旦你删除了对 AsyncTask 的引用,它就会被清理掉。如果您的 AsyncTask 阻塞,那也没关系,因为它只会挂起后台线程,并且当超时时,它将通过调用 onPostExecute() 来恢复。这也可以在不使用计时器的情况下将您的资源保持在最低限度。

这种方法需要考虑的事项。每次输入新字母时发送新请求可能会使服务器超载,因为前几个字母将产生最大的搜索结果。要么限制从服务器返回的结果数量(例如最多 10-50 个结果),要么等到他们输入足够的字符以保留结果(例如 3 个)。让用户输入更多字符的缺点是,直到 3 个字符后才会出现反馈。然而,优点是它将大大减少服务器上的点击次数。

First yes, AsyncTask is a good way to do this. The problem I see with your approach is the timer waiting to watch something die. When you invoke the asyncTask hold onto a reference of it. Let it keep state for you so you know if it's out searching or it's has returned. When the user clicks another letter you can tell that asyncTask to cancel. Something like this:

public void onClick() {
   if( searchTask != null ) {
      searchTask.cancel();
   }

   searchTask = new SearchTask( MyActivity.this ).execute( textInput.getText() );
}

public class SearchTask extends AsyncTask<String,Integer,List<SearchResult>> {
    private boolean canceled = false;

    protected onPostExecute( List<SearchResult> results ) {
       if( !canceled ) {
          activity.handleResults( results );
       }
    }

    public void cancel() {
       canceled = true;
    }
}

This is safe because onPostExecute() is on the UI thread. And cancel() is only called from the UI thread so there is no thread safety issues, and no need to synchronize. You don't have to watch a thread die. Just let the GC handle cleaning up. Once you drop the reference to the AsyncTask it will just get cleaned up. If your AsyncTask blocks that's ok because it only hangs up the background thread, and when the timeout hits it will resume by calling onPostExecute(). This also keeps your resources to a minimum without using a Timer.

Things to consider about this approach. Sending a new request everytime a new letter is typed can overload your servers because the first few letters are going to produce the largest search results. Either limit the number of results you'll return from the server (say 10-50 results max), or wait until they've entered enough characters to keep results down (say 3). The cons of making the user type more characters is the feedback doesn't kick in until 3 chars. However, the pro is it will dramatically reduce the hits on your server.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文