android - 在服务中停止多个线程

时间:2014-02-25 19:12:11

标签: java android multithreading android-service

我的活动有两个名为图片视频的复选框。在我的服务中,我正在针对这两个复选框名称 imagethread videothread 运行两个主题。如果用户检查图像复选框,我将启动服务并启动图像线程。并且如果用户取消选中它我停止服务。如果用户取消选中该框,停止服务并停止线程,我想做。现在我有两个问题

  1. 我无法停止服务中的线程

  2. 例如,如果用户取消选中视频复选框,我如何在我的 onDestroy()方法中识别出音频复选框​​已被选中,所以现在停止音频线程而不是图像,因为它已被选中。

  3. 这是我的代码剪断了我的第一个问题

    public synchronized void onDestroy() 
    {   
        image_thread_running = false;
        super.onDestroy();
    
        if(image_thread_running){
            system.out.println("stop thread"); //message is successfully printing on a console
            imageThread.interrupt(); //its not working.
    
        }
    
    }
    
    public synchronized void onStart(Intent intent, int startId) 
    {
        super.onStart(intent, startId);
    
        image_thread_running = true;
        this.intent = intent;
    
    
        String myString = intent.getStringExtra("name");
    
        if(myString.equalsIgnoreCase("image"))
        {
            if(image_thread_running){
                imageThread.start();
    
            }
    
    
        }else if(myString.equalsIgnoreCase("audio")){
            audioThread.start();
        }
    }
    
    class ImageThread extends Thread
    {
    
        @Override
        public void run()
        { 
    
    
            if (image_thread_running){
                System.out.println("Service running");
                try {
                    if(checkInternetConnection()){
                        UploadFiles();
                        Thread.sleep(interval);
                    }else{
                        Log.d("msg","internet is not connected");
                    } 
    
    
                }
            } 
            catch (InterruptedException e) 
            {
    
    
    
                e.printStackTrace();
            }
    
    
        }
    

    所以例如,如果我成功获得上面的代码工作意味着线程正在成功停止,所以它导致我的第二个问题,现在我如何识别来自视频复选框的消息以停止视频线程。因为通过更改onDestroy()中的bool值会导致更改bool值image_thread_running和video_thread_running。希望你能理解我的问题

2 个答案:

答案 0 :(得分:0)

有一段时间.stop()已被弃用,因为它可能会以不安全的方式终止您的Thread

最常见的方法是在boolean内部设置Thread控制器,检查是否发生了某些操作(在您的情况下,已选中/取消选中复选框),如果是,则在下一个循环迭代,只需在return中使用Thread即可。这将彻底和安全地终止它。您甚至可以使用它来停止服务,因此如果您退出Thread,则意味着您也必须退出Service

假设这是您CheckBox的{​​{1}}:

onClickListener()

答案 1 :(得分:0)

你需要让线程句柄中断 - 换句话说,线程必须认识到你调用了中断并做了退出线程所需的一切。

void run() {
    while(!Thread.isInterrupted()) {
        // do work
    }
}

只有在线程中执行InterruptedExceptionThread.sleep()等可中断方法时才会出现Thread.wait()。否则,它只会设置一个标记,您可以使用Thread.interrupted()Thread.isInterrupted()来检查。

因此,您需要检查线程中的状态以查看它是否已被中断,以使interrupt()调用生效。

Java theory and practice: Dealing with InterruptedException处非常清楚地解释了这一点。

  

每个线程都有一个与之关联的布尔属性   它的中断状态。中断状态最初为假;   当一个线程被某个其他线程通过调用中断时   Thread.interrupt(),两件事之一发生。如果该线程是   执行低级可中断阻塞方法,如   Thread.sleep(),Thread.join()或Object.wait(),它取消阻塞和   抛出InterruptedException。否则,interrupt()只会设置   线程的中断状态。代码在中断的线程中运行   以后可以轮询中断状态以查看是否已请求   停止它正在做的事;可以读取中断状态   Thread.isInterrupted()可以在单个中读取和清除   使用命名不佳的Thread.interrupted()进行操作。

该页面还解释了如何处理InterruptedException


对于您在图片主题中所做的工作(上传文件),我建议您使用IntentService。使用IntentService还会将任务与活动的生命周期分离,例如,它可以继续进行方向更改,或在用户导航到其他活动后完成其工作。与Service不同,IntentService在单独的线程中运行,处理工作线程将由您负责。 (您也可以轻松地实现任务队列,或者从一个任务链接到另一个任务,只需处理onHandleIntent中的不同操作。)