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.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
答案 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);
}
}