【问题标题】:Thread doesn't stop on calling stopService() in MainActivity在 MainActivity 中调用 stopService() 时线程不会停止
【发布时间】:2015-05-30 09:24:23
【问题描述】:

主活动

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): 已创建

03-26 16:48:45.065: D/tag(15674): 服务开始

03-26 16:48:45.065: D/tag(15674): 正在运行

03-26 16:48:45.495: D/tag(15674): 正在运行

03-26 16:48:46.065: D/tag(15674): 正在运行

03-26 16:48:46.495:D/tag(15674):正在运行

03-26 16:48:47.065: D/tag(15674): 正在运行

03-26 16:48:47.495: D/tag(15674): 正在运行

03-26 16:48:48.065: D/tag(15674): 正在运行

03-26 16:48:48.505: D/tag(15674): 正在运行

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

03-26 16:48:49.065: D/tag(15674): 正在运行

03-26 16:48:49.495: D/tag(15674): 正在运行

【问题讨论】:

  • 你正在你的服务中创建一个新线程,你并没有停止......所以它会运行
  • @PreethiRao 我在 onDestroy() 中停止它
  • 你不应该使用 Thread.stop() 它已被弃用..
  • @PreethiRao 那我应该用什么?

标签: java android multithreading service


【解决方案1】:

试试这个..

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

并且在您的服务中有一个对可运行对象的引用并调用 stopRunning() 方法...

【讨论】:

  • 我找到了更有效的解决方案,还是谢谢
【解决方案2】:

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

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

需要注意的是,run()方法的访问是由isAlive()方法执行的,它也用于检查是否没有更多的销毁动作。

重新编写的代码使用 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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多