简体   繁体   English

如何在Android上停止线程?

[英]How to stop the thread on Android?

I have a function parseData which recieves Vector of urls and gives them to DataParser. 我有一个函数parseData,它接收URL的Vector并将它们提供给DataParser。 DataParser gets data from urls and parses it. DataParser从URL获取数据并进行解析。 The problem is that user might request new urls to parse before previous parsingis finished. 问题在于用户可能会在先前的解析完成之前请求新的URL进行解析。 In that case previous data becomes irrelivant but thread continues to work. 在那种情况下,先前的数据变得无关紧要,但是线程继续工作。 Since there might be a lot of urls in one request and parsing each of them takes time, after 5-6 sequential requests phone starts work very slowly. 由于一个请求中可能包含许多网址,并且解析每个网址都需要花费时间,因此在5-6次连续请求之后,电话启动会非常缓慢。

Here is the code snippet. 这是代码片段。

public void parseData(final String key, final Vector<String> data)
{
    this.key = key;
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            DataParser dp = new DataParser(key);
            dp.setData(data);
            dp.startParse();
        }
    });
    thread.start();
}

I think the solution might be to keep extra flag in DataParser. 我认为解决方案可能是在DataParser中保留额外的标志。 Since it requesting urls in cycle, I can check flag and break cycle, but it seems to me rude. 由于它在周期内请求url,因此我可以检查标志和中断周期,但是对我来说似乎很粗鲁。

Are there other ways to solve this issue? 还有其他方法可以解决此问题吗?

You can use interrupt() method: 您可以使用interrupt()方法:

thread.interrupt();

BTW, checking some kinds of flags isn't so rude and bad style. 顺便说一句,检查某些标志并不是那么粗鲁和糟糕的风格。 But don't forget to declare such flag as volatile . 但是不要忘记将此类标志声明为volatile

You need to check periodically for a flag in worker thread. 您需要定期检查工作线程中的标志。 Set that flag if worker thread is to be stopped. 如果要停止工作线程,则设置该标志。

You could constantly check on a boolean flag every time you perform a parsing operation, and stop parsing if this flag becomes true. 您可以在每次执行解析操作时不断检查布尔值标志,并在该标志变为true时停止解析。

From another thread, you can establish the value of this flag to "cancel" the parsing. 您可以从另一个线程建立此标志的值,以“取消”解析。

This is the technique AsyncTasks use to cancel the work done in doInBackground(). 这是AsyncTasks用于取消在doInBackground()中完成的工作的技术。

class DataParser {
   private boolean volatile mIsCancelled = false;

   public void startParsingAsync() {
       new Thread(new Runnable(
                 public void run() {
                      parse();
                 } 
       )).start();
   }

   private void parse() {
          while(!isCancelled()) {
              parseNextNode();
          }
   }

   private synchronized void isCancelled() {
        return mIsCancelled();
   }

   public synchronized void cancel() {
       mIsCancelled = true;
   }

   private void parseNextNode() {
     .....
   }

From another thread, you can invoke the method cancel() once the data has become irrelevant. 一旦数据变得无关紧要,则可以从另一个线程调用cancel()方法。

Note the you have to synchronize the access to the flag, as it will be accessed from different threads. 请注意,您必须同步对标志的访问,因为将从不同线程访问该标志。

This code is not tested, so it may not even compile... 此代码未经测试,因此可能甚至无法编译...

That's the theory, but for practical uses, you should use an AsyncTask, which gives the cancelling for you. 这是理论,但是对于实际使用,您应该使用AsyncTask,它为您提供取消功能。

This kind of thing is done well in an Async Task instead of straight thread. 这种事情在异步任务而不是直接线程中做得很好。 There is a cancel method to them and an is canceled function that can tell you to stop. 有一个取消方法,它们是一个被取消的功能,可以告诉您停止。

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

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