Note that there are some explanatory texts on larger screens.

plurals
  1. POStopping Service results in orphaned thread
    primarykey
    data
    text
    <p>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.</p> <pre><code> 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)); } }); } } </code></pre> <p>The <a href="http://developer.android.com/guide/topics/fundamentals/services.html" rel="nofollow">documentation</a> 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.</p> <pre><code> 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++ &gt; 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); } } </code></pre> <p>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?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload