简体   繁体   中英

Thread doesn't stop on calling stopService() in MainActivity

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);

        }
    });
}
}

Serv

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;
}

}

When I click on the button to StopService, the ondestroy() message is called but my thread keeps on running. Log is given below:

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.065: 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

try this out ..

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;
 }

And in your service have a reference to the runnable object and call stopRunning() method...

The code suggests some share variables problems. This code uses references in a non-appropriate way. For example, ac=new Thread(new bob()) uses a new instance reference for bob() class but does not control it on while(true){…} loop. In addition, to use a while(true) or while(1==1) is a bad practice because this can crash all the application. See for example on GitHub . These are very bad codes that could produce unexpected things.

I re-work your example using a semaphore approach. In this case, I define a private Boolean semaphore variable that controls the access to the while loop.

It is very important to notice that the access to run() method is performed by isAlive() method, it also is used to check if the there is no more to do on destroyng action.

The code re-worked uses the natural monitor control existing on JVM. In this case, recommended from the Java documentation

Thread.stop() - Deprecated . This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked [...]. Many uses of the stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. [...]

This approach can be easily adapted to Android or others Java environments.


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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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