线程不会在MainActivity中调用stopService()时停止

时间:2015-03-26 11:21:24

标签: java android multithreading service

MainActivity

public class MainActivity extends ActionBarActivity {

Context c=this;
Intent i;
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button b=(Button)findViewById(R.id.button1);
    Button b1=(Button)findViewById(R.id.button2);

    b.setOnClickListener(new OnClickListener() {

        public void onClick(View v)
        {
        i=new Intent(c,serv.class);
        startService(i);
        }
    });

    b1.setOnClickListener(new OnClickListener()
    {

        public void onClick(View v) {

            stopService(i);

        }
    });
}
}

提供商

class bob implements Runnable{
Thread ac;

public void run() 
{
    while(true)
    {
        Log.d("tag","RUNNING");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}   }
public class serv extends Service {
Thread ac;


public void onCreate() {
        Log.d("tag","CREATED");
        super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("tag","SERVICE STARTED");

    ac=new Thread(new bob());
    ac.start();


    return Service.START_NOT_STICKY;

}

@Override
public void onDestroy() {
    Log.d("tag","DESTROYED");
try{
    ac.stop();
}catch(Exception e)
{e.printStackTrace();}


}

public IBinder onBind(Intent arg0) {
    return null;
}

}

当我点击StopService按钮时,会调用ondestroy()消息,但我的线程一直在运行。 记录如下:

  

03-26 16:48:45.065:D / tag(15674):CREATED

     

03-26 16:48:45.065:D / tag(15674):SERVICE STARTED

     

03-26 16:48:45.065:D / tag(15674):RUNNING

     

03-26 16:48:45.495:D / tag(15674):RUNNING

     

03-26 16:48:46.0​​65:D / tag(15674):RUNNING

     

03-26 16:48:46.495:D / tag(15674):RUNNING

     

03-26 16:48:47.065:D / tag(15674):RUNNING

     

03-26 16:48:47.495:D / tag(15674):RUNNING

     

03-26 16:48:48.065:D / tag(15674):RUNNING

     

03-26 16:48:48.505:D / tag(15674):RUNNING

     

03-26 16:48:48.615:D / tag(15674):DESTROYED

     

03-26 16:48:49.065:D / tag(15674):RUNNING

     

03-26 16:48:49.495:D / tag(15674):RUNNING

2 个答案:

答案 0 :(得分:0)

尝试一下..

class bob implements Runnable{
Thread ac;
boolean isRunning = true;
public void run() 
{
    while(isRunning)
    {
        Log.d("tag","RUNNING");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

} 
 public void stopRunning()
{
isRunning = false;
 }

在你的服务中有一个对runnable对象的引用并调用stopRunning()方法......

答案 1 :(得分:0)

代码表明了一些共享变量问题。此代码以不合适的方式使用引用。例如,ac=new Thread(new bob())对bob()类使用新的实例引用,但不在while(true){…}循环上控制它。此外,使用while(true)while(1==1)是一种不好的做法,因为这会导致所有应用程序崩溃。 See for example on GitHub。这些代码非常糟糕,可能产生意想不到的事情。

我使用信号量方法重新处理您的示例。在这种情况下,我定义了一个private Boolean semaphore变量来控制对while循环的访问。

非常重要的是要注意run()方法的访问是由isAlive()方法执行的,它还用于检查在destroyng操作上是否还有其他操作。

重新编写的代码使用JVM上现有的自然监视器控件。在这种情况下,建议从Java documentation

  

Thread.stop() - 已弃用。这种方法本质上是不安全的。使用Thread.stop停止线程会导致它解锁已锁定的所有监视器[...]。停止的许多用法应该由代码修改,该代码只是修改某个变量以指示目标线程应该停止运行。 [...]

这种方法可以很容易地适应Android或其他Java环境。


class MainActivity{
    private Service service;
    public MainActivity(){
        service = new Service();
    }
    public void startService(){
        service.onCreate();
        service.onStartCommand();
    }
    public void stopService(){
        service.onDestroy();

    }
}

class Bob implements Runnable{
    private Boolean semaphore;
    public Bob(){
        this.semaphore = Boolean.FALSE;
    }

    public void active(){
        this.semaphore = Boolean.TRUE;
    }

    public void deactivate(){
        this.semaphore = Boolean.FALSE;
    }

    public Boolean isAlive(){
        return this.semaphore;
    }

    @Override
    public void run() {
        while( isAlive() ){
            System.out.println("RUNNING");
            sleep();
        }
    }

    private void sleep() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) { e.printStackTrace(); }
    }
}
class Service{
    private static final int START_NOT_STICKY = 1;
    private Thread sThread;
    private Bob rBob;

    public Service(){
        this.rBob    = new Bob();
        this.sThread = new Thread( rBob );
    }

    public void onCreate() {
        System.out.println("CREATED");
    }

    public int onStartCommand() {
        System.out.println("SERVICE STARTED");

        rBob.active();
        sThread.start();

        return Service.START_NOT_STICKY;
    }

    public void onDestroy() {
        rBob.deactivate();
        if( sThread.isAlive() && !rBob.isAlive() ) {
            System.out.println("DESTROYED");
        }
    }
}
public class SampleThreadTest {

    public static void main(String a[]) throws InterruptedException {
        MainActivity ma = new MainActivity();

        Thread.sleep(1000);
            ma.startService();
        Thread.sleep(5000);
            ma.stopService();
        Thread.sleep(5000);
    }
}