停止服务会导致孤立的线程 [英] Stopping Service results in orphaned thread

查看:109
本文介绍了停止服务会导致孤立的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继续从书临Android的2,通过包括两个类的服务示例工作研究:BackgroundService.java和MainActivity.java。 MainActivity类别如下图所示,并有几个按钮。取消绑定按钮,unbindBtn,停止服务,但似乎并没有做很多别的喜欢杀死线程服务启动。

I am continuing to study from the book "Pro Android 2," working through the Service example that consists of two classes: BackgroundService.java and MainActivity.java. The MainActivity class is shown below and has a couple buttons. The unbind button, unbindBtn, stops the Service but doesn't appear to do much else like kill the thread the Service started.

    public class MainActivity extends Activity {
        private static final String TAG = "MainActivity";

        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            Log.d(TAG, "starting service");

            Button bindBtn = (Button)findViewById(R.id.bindBtn);
            bindBtn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View arg0) {
                    Intent backgroundService = new Intent(MainActivity.this, com.marie.mainactivity.BackgroundService.class);
                    startService(backgroundService);
                }
            });

            Button unbindBtn = (Button)findViewById(R.id.unbindBtn);
            unbindBtn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    stopService(new Intent(MainActivity.this, BackgroundService.class));
                }
            });
        }
    }

借助文档说:如果你的服务是打算做任何CPU密集型工作或阻塞操作...,你应该在服务中创建一个新的线程来完成这项工作。而这正是BackgroundService类下面呢。正如你可以看到下面,我在线程的run增加了,而(真)环()方法,看的时候我停止服务发生了什么主题。

The documentation says "if your service is going to do any CPU intensive work or blocking operations..., you should create a new thread within the service to do that work." And that's exactly what the BackgroundService class does below. As you can see below I've added a while(true) loop in the thread's run() method to see what happens to the thread when I stop the Service.

    public class BackgroundService extends Service {
        private NotificationManager notificationMgr;

        @Override
        public void onCreate() {
            super.onCreate();

            notificationMgr = NotificationManager)getSystemService(NOTIFICATION_SERVICE);

            displayNotificationMessage("starting Background Service");

            Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService");
            thr.start();
        }   

        class ServiceWorker implements Runnable
        {
            public void run() {
                // do background processing here...

                long count = 0;
                while (true) {
                    if (count++ > 1000000)
                    {
                        count = 0;
                        Log.d("ServiceWorker", "count reached");
                    }
                }

                //stop the service when done...
                //BackgroundService.this.stopSelf();
            }
        }

        @Override
        public void onDestroy()
        {
            displayNotificationMessage("stopping Background Service");
            super.onDestroy();
        }

        @Override
        public void onStart(Intent intent, int startId) {
            super.onStart(intent, startId);
        }

        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        private void displayNotificationMessage(String message)
        {
            Notification notification = new Notification(R.drawable.note, message, System.currentTimeMillis());

            PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);

            notification.setLatestEventInfo(this, "Background Service", message, contentIntent);

            notificationMgr.notify(R.id.app_notification_id, notification);
        }
    }

当我preSS的解除绑定按钮,unbindBtn,在MainActivity类,我相信在这个例子中,服务将被停止。但是,从我所看到的logcat中已启动的服务继续运行的线程。这就像线程现在是某种孤儿,没有明显的方式来阻止它。我见过的其他来源的code在线程的run()方法使用whil​​e(true)循环。除非提供跳出循环的一种方式,这似乎不好。是通常它是如何做?还是有其他的方式来杀死启动它停止服务后,一个线程?

When I press the unbind button, unbindBtn, in the MainActivity class I trust the Service in this example will be stopped. But from what I can see in logcat the thread that was started by the Service continues to run. It's like the thread is now some kind of orphan with no apparent way to stop it. I've seen other source code use a while(true) loop in a thread's run() method. This seems bad unless a way to break out of the loop is provided. Is that typically how it's done? Or are there other ways to kill a thread after the Service that started it has stopped?

推荐答案

您应该提供一个跑步布尔

while(running) {
    //do your stuff
}

您想使它的东西,你可以更新。的也许你的服务 的onDestroy()方法应该叫 stopProcessing()的方法你的的Runnable ,这将在运行布尔设置为

You want to make it something that you can update. Perhaps your Service's onDestroy() method should call a stopProcessing() method on your Runnable, which will set the 'running' boolean to false.

这篇关于停止服务会导致孤立的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆