As far as I know, when I rotate the screen, the activity is destroyed and recreated. In the following scenario, it seems that this is not always the case. So the question is: is it really destroyed? For some reason, am I losing my memory? If it is not destroyed, is it running in the same thread as the newly created activity?
A script is a "vertical" action that runs an IntentService, it takes 5 seconds to complete a service and uses ResultReceiver to send the result. During these 5 seconds, the screen rotates and a new “horizontal” activity is created. The result returns to "vertical" activity, and not to the new "horizontal". So, "vertical" activity is not destroyed?
I created a project demonstrating this. Here is the code.
First xml with action layout. Just two buttons.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show value of variable" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start IntentService" />
</LinearLayout>
After that, our IntentService
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 < 5000);
receiver.send(0, null);
}
}
And finally, activity
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);
}
}
When the action is run for the first time, mTestVar is 0, and onCreate is equal to 1. When the action is destroyed, it saves the value. The next action loads it and increments it to 2, etc.
Following these steps:
- Press button 1: mTestVar - 1
- Press 2: service start
- Rotate the screen for up to 5 seconds.
- Press Button1: mTestVar - 2 (called onCreate)
- Wait for 5 seconds to elapse: mTestVar is shown as a value of 1
As far as I can see, this means that the first action has not been destroyed. Did I miss something?
Thank!
EDIT
, MAT , , , , , . , .
, , . , . , .