title: IntentService prevents activity from destroying
body: <p>As far as i know, when i rotate the screen, the activity gets destroyed and recreated. In the following scenario, it looks like this is not always the case. So the question is: Is it really destroyed? Am i leaking memory for some reason? If it is not destroyed, does it run on the same thread as the newly created activity?</p>
  
  <p>The scenario is an "vertical" Activity that starts an IntentService, the service takes 5 secs to complete, and uses a ResultReceiver to send back the result. During those 5 secs, the screen gets rotated, and a new "horizontal" activity gets created. The result gets back to the "vertical" activity, not the new "horizontal". So, the "vertical" activity is not destroyed?</p>
  
  <p>I've created a project to demonstrate this. Here comes the code.</p>
  
  <p>First, the xml with the activity layout. Just two buttons.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical" &gt;
  
      &lt;Button
          android:id="@+id/button1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Show value of variable" /&gt;
  
      &lt;Button
          android:id="@+id/button2"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Start IntentService" /&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>After that, our IntentService</p>
  
  <pre><code>public class SomeService extends IntentService {
  
      public SomeService(){
          super("SomeService");
      }
  
      @Override
      protected void onHandleIntent(Intent intent) {
          ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
  
          long t0, t1;
          t0 = System.currentTimeMillis();
          do {
              t1 = System.currentTimeMillis();
          } while (t1-t0 &lt; 5000);
  
          receiver.send(0, null);
      }
  }
  </code></pre>
  
  <p>And finally the activity</p>
  
  <pre><code>public class TestActivityDestructionActivity extends Activity {
  
      private int mTestVar = 0;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
  
          if (savedInstanceState != null){
              mTestVar = savedInstanceState.getInt("tv");
          }
  
          mTestVar++;
  
          Button b1 = (Button) findViewById(R.id.button1);
          b1.setOnClickListener(new View.OnClickListener() {
              public void onClick(View v) {
                  Toast.makeText(TestActivityDestructionActivity.this, "Value: " + mTestVar, Toast.LENGTH_SHORT).show();
              }
          });
  
          Button b2 = (Button) findViewById(R.id.button2);
          b2.setOnClickListener(new View.OnClickListener() {
              public void onClick(View v) {
                  Intent intent = new Intent(TestActivityDestructionActivity.this, SomeService.class);
                  intent.putExtra("receiver", new SomeReceiver(new Handler()));
                  startService(intent);
                  Toast.makeText(TestActivityDestructionActivity.this, "IntentService started", Toast.LENGTH_SHORT).show();
              }
          });
  
      }
  
      private class SomeReceiver extends ResultReceiver{
          public SomeReceiver(Handler handler) {
              super(handler);
          }
  
          @Override
          protected void onReceiveResult(int resultCode, Bundle resultData) {
              super.onReceiveResult(resultCode, resultData);
              Toast.makeText(TestActivityDestructionActivity.this, "Receiver value: " + mTestVar, Toast.LENGTH_SHORT).show();
          }
      }
  
      @Override
      protected void onSaveInstanceState(Bundle outState) {
          super.onSaveInstanceState(outState);
          outState.putInt("tv", mTestVar);
      }
  }
  </code></pre>
  
  <p>When the activity starts the first time, mTestVar is 0, and onCreate it is inceased to 1. When the activity gets destroyed, it saves the value. The next activity loads it and increases it to 2, and so on.</p>
  
  <p>Following these steps:</p>
  
  <ol>
  <li>Click Button1 : mTestVar is 1</li>
  <li>Click Button2 : Service gets started</li>
  <li>Rotate screen before 5 secs elapse</li>
  <li>Click Button1 : mTestVar is 2 (the onCreate was called)</li>
  <li>Wait for the 5 secs to elapse : mTestVar is shown as still having a value of 1</li>
  </ol>
  
  <p>As far as i can see, that means that the first activity was not destroyed. Am i missing something?</p>
  
  <p>Thanks!</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>After seeing the answer to this question, i used MAT and heap dumps and found out that the first activity is never Garbage Collected, even though the service is long gone and garbage collected and there is no reference to the activity anymore. I don't know why.</p>
  
  <p>However, if the receiver is never created and never passed to the service, there is no memory leak. The first activity is destroyed as expected. There is no reason not to, anyway.</p>