简体   繁体   English

如何停止后台/工作线程并重新启动?

[英]How to stop background/worker thread and start again?

I have an Activity class which has a EditText field. 我有一个Activity类,其中有一个EditText字段。 Every time a user enters more than 2 letters i start a service using StartService() which search through a list of country names. 每次用户输入两个以上的字母,我就会使用StartService()启动服务,该服务会搜索国家名称列表。 This service starts a background/worker thread using - 此服务使用-启动后台/工作线程

AsyncTask backgoundTask = new AsyncTask;
backgoundTask.execute(givenString);

And in the doInBackground() function of AsyncTask class i start searching in a list of country names which contains those two letters. 在AsyncTask类的doInBackground()函数中,我开始搜索包含这两个字母的国家/地区名称列表。

protected Void doInBackground(String[] objects) {
                Log.i("doInBackground()",Thread.currentThread().getName());
                //code to check if country name contains those two/more letters 
                return null;
}

Issue i am having is- Suppose i type two letter and the service starts which starts searching in the list of country names. 我遇到的问题是-假设我输入两个字母,然后服务开始,该服务开始在国家/地区名称列表中进行搜索。 Then i type the 3rd letter and it hits the service again which again search in the list of country names while the other on in progress. 然后,我输入第三个字母,它再次点击服务,该服务再次在国家名称列表中搜索,而另一个正在进行中。 The searches does not run simultaneously. 搜索不会同时运行。 first the search goes on for 2 letters input and then it goes on for 3 letters input. 首先搜索输入2个字母,然后搜索3个字母。

What i need is- if a search is already going on, then stop that search and start again with new set of letters. 我需要的是-如果搜索已经在进行中,则停止该搜索,然后从一组新字母开始。 For example- if search is already going on for 2 letters input, when user enters 3rd letter, stop the previous search with 2 letters and start with 3 letters. 例如,如果搜索已经在进行2个字母的输入,则当用户输入第3个字母时,以2个字母停止上一个搜索,以3个字母开始。

I tried- calling stopService() first when input is more than 2 letters and then startService(). 我尝试过-当输入超过2个字母时先调用stopService(),然后再调用startService()。 But its did not work. 但是它没有用。 I can see in Logcat that search went through the full list of country names once and then again for the 3 letters. 我可以在Logcat中看到搜索一次又一次遍历了国家名称的完整列表,然后再一次搜索3个字母。

I am using started service. 我正在使用开始服务。 I am thinking of using intent service. 我正在考虑使用意图服务。 Any suggestion greatly appreciated. 任何建议,不胜感激。 thank you. 谢谢。

*********-- Update --************ *********- 更新 -************

Thank all of you for suggesting backgroundtask.cancel(). 感谢大家提出的backgroundtask.cancel()建议。 this is what i did - 这就是我所做的-

@Override
        protected void onCancelled() {
            super.onCancelled();
            Log.i("onCancelled()",Thread.currentThread().getName());
            //findHost(objects[0]);
        }


        @Override
        protected Void doInBackground(String[] objects) {
            Log.i("doInBackground()",Thread.currentThread().getName());
            if(backgoundTask.isCancelled()){
                findCountry(objects[0]);
            }else{
                backgoundTask.cancel(true);
                Log.i("Running()","Background task running again");
                findCountry(objects[0]);
            }

            return null;
        }

But the service is still searching country name twice or as many time as user input is more than 2 letters. 但是,该服务仍在搜索国家/地区名称两次,或者是用户输入超过2个字母的次数。

What I'd do is use AutoCompleteTextView, check out link below: 我要做的是使用AutoCompleteTextView,请查看下面的链接:

https://developer.android.com/reference/android/widget/AutoCompleteTextView.html https://developer.android.com/reference/android/widget/AutoCompleteTextView.html

Though you are trying to stop your service, the async task is still alive on the thread. 尽管您试图停止服务,但异步任务仍在线程上运行。 You need to make sure backgoundTask.cancel(true) gets called as well, possibly in the onStop() method of your service. 您需要确保还可以在服务的onStop()方法中调用backgoundTask.cancel(true)

Always use cancel() to stop a AsyncTask before starting the new task: 在开始新任务之前,请始终使用cancel()停止AsyncTask:

backgoundTask.cancel(true);

The documentation of AsyncTask provide details in the 'Cancelling a task' section: AsyncTask文档在“取消任务”部分中提供了详细信息:

A task can be cancelled at any time by invoking cancel(boolean) . 可以通过调用cancel(boolean)随时取消任务。 Invoking this method will cause subsequent calls to isCancelled() to return true. 调用此方法将导致对isCancelled()的后续调用返回true。 After invoking this method, onCancelled(Object) , instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. 调用此方法后,onCancelled(对象),而不是onPostExecute(对象)doInBackground之后被调用(对象[])返回。 To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]) , if possible (inside a loop for instance.) 为了确保尽快取消任务,应始终从doInBackground(Object [])定期检查isCancelled()的返回值(如果可能)(例如在循环内)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM