杀死线程

发布于 2024-09-30 18:39:40 字数 293 浏览 0 评论 0 原文

我创建了一个类,它是 Thread 的扩展。此类访问 Web 服务并在屏幕上显示一些数据。我不关心保存这些数据(屏幕显示搜索结果)。

目前,用户只需在 EditText 中键入内容并单击搜索按钮即可。我想取消搜索按钮并实现类似于 Google 即时搜索的功能,当您键入时,搜索结果就会更新。

这意味着,随着用户输入,搜索参数会发生变化。 我希望能够终止当前正在运行的线程(如果当前正在运行)并使用新的搜索字符串生成一个新线程。如何才能实现这一目标?我可以使用 Thread 来完成它还是需要使用一个新对象?

I've created a class which is an extension of Thread. This class hits a web service and throws some data on screen. I don't care about persisting this data (the screen displays search results).

Currently, the user simply types into an EditText and clicks a search button. I'd like to take away the search button and implement something similar to Google's Instant Search where, as you type, the search results get updated.

This means, as the user types, the search parameters change. I want to be able to kill the currently running thread (if one is currently running) and spawn a new one with the new search string. How can this be achieved? Can I do it with Thread or will I need to use a new object?

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

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

发布评论

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

评论(4

暗恋未遂 2024-10-07 18:39:40

这比简单地杀死一个线程更困难。您可以在线程上调用interrupt(),但线程必须定期检查其中断状态并自行终止。

其次,您不希望在用户键入时立即启动线程。线程的产生很快就会压垮系统。在执行搜索之前等待 100-200 毫秒,以便您可以合理确定用户已完成输入。谷歌的服务器可以处理负载,但手机无法处理。

编辑:扩展我的第一点,线程可能很难取消。在这种情况下,事件调度线程需要以某种方式告诉正在运行的线程它需要停止。您可以使用线程中内置的中断功能,但正如本文。相反,我只需要一个布尔变量,可以通过某些外部线程将其设置为取消。技巧(如该链接所示)是您需要定期检查线程是否已被取消,如果是,您将需要手动中止。

您将遇到的下一个问题是是否已经对某个外部服务器进行了网络调用。它将阻塞在该线程中,直到它返回并且该线程将无法杀死自己。这可能需要几秒钟。

那么让我们来解决这个问题 - 如果用户键入一个字符,并且超时期限由于某种原因到期并且进行了 Web 调用,然后用户键入了另一个字符,超时期限到期了,因此进行了另一个 Web 调用,该怎么办?如果您的 Web 调用需要 5 秒,则第一个线程将继续运行至少 5 秒,即使事件调度线程取消它也是如此。您现在有两个线程进行网络调用。

现在扩展一下。如果用户执行此操作并创建 4 或 5 个线程怎么办?这就是您耗尽手机资源的地方。我并不是告诉你不要这样做,只是想指出该领土带来的潜在问题。

This is more difficult than simply killing a thread. You can call interrupt() on the thread, but the thread will have to check its interrupt status periodically and self-terminate.

Secondly, you will not want to start a thread immediately on a user typing. You will quickly overwhelm the system with thread spawning. Implement a wait period of 100-200 milliseconds before doing the search so that you can be reasonably sure the user is done typing. Google's server can handle the load, but the handset won't be able to.

EDIT: to expand on my first point, threads can be difficult to cancel. In this case the event dispatch thread will need to somehow tell the running thread it needs to stop. You can use the interrupt facility built into threads, but it tends to be touchy as pointed out by this article. Instead, I would simply have a boolean variable that can be set to cancelled by some outside thread. The trick (like shown in that link) will be that you will need to periodically check if the thread has been cancelled, and if so you will need to manually abort.

The next problem you will run into is if a web call has already been made to some outside server. It will block in that thread until it comes back and the thread will not be able to kill itself. This could take several seconds.

So let's play this out - what if a user types a character, and your timeout period expires for whatever reason and a web call is made, then the user types another character where the timeout period expires so another web call is made? If your web calls take 5 seconds, then the first thread will continue to run, even if the event dispatch thread cancels it, for at least 5 seconds. You now have two threads making web calls.

Now expand that. What if a user does this and makes 4 or 5 threads? This is where you overwhelm the resources of your handset. I am not telling you not to pursue this, just trying to point out the potential problems that come with the territory.

倾城月光淡如水﹏ 2024-10-07 18:39:40

使用 AutoCompleteTextView 小部件。从 Web 服务中预取搜索提示,将其加载到自动完成数组中并设置其适配器。根据提示的复杂程度,可以选择使用自定义光标适配器。

类似:

AutoCompleteTextView inputSearch;
String[] autocompleteArray = new String[size of prefetched items];
//fill autocompleteArray with webservice data

inputSearch = (AutoCompleteTextView)findViewById(R.id.inputSearch);
searchAdapter = new ArrayAdapter<String>(context, R.layout.autcomplete_dropdown, autocompleteArray);
inputSearch.setAdapter(searchAdapter);

R.layout.autocomplete_dropdown 可能类似于:

<?xml version="1.0" encoding="utf-8"?>
<TextView 
  xmlns:android="http://schemas.android.com/apk/res/android" 
  android:id="@+id/name"
  android:singleLine="false"
  android:textSize="15sp"
  android:paddingLeft="3dip"
  android:paddingRight="3dip"
  android:paddingTop="15dip"
  android:paddingBottom="15dip"
  android:textColor="#000000"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" /> 

在应用程序中进行搜索,您要搜索的内容有多大?预加载 sqlite 中的所有数据并经常检查来自网络的更新数据?

否则我会说你应该限制你的应用程序尝试启动线程的次数。设置某种计时器,它将:
看看...

  1. 线程是否已经在工作
  2. 输入自上次以来已更改
    时间或具有非空搜索值,
  3. 用户甚至在搜索中
    屏幕

如果一切正常,启动一个线程来获取结果

只是一个想法,还没有尝试过这个

Use the AutoCompleteTextView widget. prefetch your search hints from your web service to load them into the autocomplete array and set its adapter. optionally use a custom cursor adapter depending on how complex your hints are.

something like:

AutoCompleteTextView inputSearch;
String[] autocompleteArray = new String[size of prefetched items];
//fill autocompleteArray with webservice data

inputSearch = (AutoCompleteTextView)findViewById(R.id.inputSearch);
searchAdapter = new ArrayAdapter<String>(context, R.layout.autcomplete_dropdown, autocompleteArray);
inputSearch.setAdapter(searchAdapter);

R.layout.autocomplete_dropdown could look something like:

<?xml version="1.0" encoding="utf-8"?>
<TextView 
  xmlns:android="http://schemas.android.com/apk/res/android" 
  android:id="@+id/name"
  android:singleLine="false"
  android:textSize="15sp"
  android:paddingLeft="3dip"
  android:paddingRight="3dip"
  android:paddingTop="15dip"
  android:paddingBottom="15dip"
  android:textColor="#000000"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" /> 

do your searching in the app, how large is the content you will be searching? pre-load all the data in sqlite and check for updated data from the web every so often perhaps?

otherwise i'd say you should limit the amount of times your app tries to start a thread. setup some sort of timer that will:
see if...

  1. a thread is already working
  2. the input has changed since the last
    time or has a non-empty search value
  3. the user is even on the search
    screen

if everything is OK, start up a thread to get results

just a thought, haven't tried this

望笑 2024-10-07 18:39:40

线程创建是一个非常耗时的操作。因此,我建议有一个线程随后使用新的搜索字符串调用 Web 服务。

Thread creating is very consuming operation. Thus I would recommend have one thread which will subsequently call webservices with new search strings.

謌踐踏愛綪 2024-10-07 18:39:40

您的意思是自动完成。我认为您不需要启动几个线程来处理这个问题。使用 android 自动完成 并使用 AutoCompleteTextView

此外,不建议通过子类化 java 线程或实现接口来使用线程。您可以使用 AsyncTask 在后台执行耗时的操作。

What you mean is Auto Complete. I don't think you need to start a couple of threads to handle that. Work with android Auto Complete and use AutoCompleteTextView.

Furthermore it is not recommended to use threads by subclassing java thread or implementing the interface. You can use AsyncTask to perform time consuming operations in the background.

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