Question on the life cycle of activities and the removal / allocation of resources

I was very puzzled by this life cycle, so I did a little experiment. In short: the result shows that when a process is created after its destruction, the user interface objects selected in the last session have disappeared and need to be restored (which is expected). But another memory space allocated in the last session is still available for this session.

For me, the surprise is: the objects of the system UI (for example, ListView) and the memory space allocated by me are not destroyed at the same time. Why don't they die (or survive) at the same time?

Look here:

public class PracticeActivity extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // If there is left-over value in G.count[99], then do not populate // the ListView. if (G.count[99] == 0) { ListView lv = getListView(); lv.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, m_Starbucks)); } Log.d("TAG", MessageFormat.format("Created, count = {0,number}", G.count[99])); Log.d("TAG", MessageFormat.format("Starbucks = {0}", m_Starbucks[0])); G.count[99]++; // increment the count m_Starbucks[0] = "Coffee Frappuccino"; // and change the menu } @Override public void onRestart() { super.onRestart(); Log.d("TAG", "Restarted"); } @Override public void onStart() { super.onStart(); Log.d("TAG", "Started"); } @Override public void onResume() { super.onResume(); Log.d("TAG", "Resumed"); } @Override public void onPause() { super.onPause(); Log.d("TAG", "Paused"); } @Override public void onStop() { super.onStop(); Log.d("TAG", "Stopped"); } @Override public void onDestroy() { super.onDestroy(); if (isFinishing()) Log.d("TAG", "Destroyed -- someone finished me"); else Log.d("TAG", "Destroyed -- system needs resources"); } private static final String[] m_Starbucks = { "Latte", "Cappuccino", "Caramel Macchiato", "Americano", "Mocha", "White Mocha", "Mocha Valencia", "Cinnamon Spice Mocha", "Toffee Nut Latte", "Espresso", "Espresso Macchiato", "Espresso Con Panna" }; } 

Here is the class G defined in the G.java file:

 public class G { public static int[] count = new int[100]; } 

Running this test gave the following results:

 Created, count = 0 Starbucks = Latte Started Resumed Paused Stopped Destroyed -- someone finished me Created, count = 1 Starbucks = Coffee Frappuccino Started Resumed 

In the first session, the value of count [99] was 0, so the program switched to populating the ListView, so everything was in order.

In the second session, the counter [99] still stores the value remaining from the first session, so the program did not populate the ListView, in the hope that the ListView will also be available. But this is not so, the result is a black screen. This means that G.count [] was saved (and therefore m_Starbucks []) from the last session, but the ListView was not saved.

Obviously, in this system there is only one instance of PracticeActivity, when this instance dies, both PracticeActivity and G must die too. But they didn’t do this; they still retain values ​​from the last session.

QUESTIONS:

  • If count [] and m_Starbucks [] are still available, then that means PracticeActivity and G - both live too. Then why did the ListView pass? Do not everyone die or live at the same time?
  • When I see some of my classes' members adhere to their old values ​​from the last session, can I assume that all members of my classes are also valid ??? Ie, does Android kill my resources in an all or worthless mod? Or can he remove some and leave others? (This question should not have existed in the first place, but seeing the result of the experience, one begins to be surprised.)

Can anyone shed some light on this? Very much appreciated.

+4
source share
2 answers

Static class members live as long as the JVM (DVM) lives - which can be (and, of course,) longer than the life cycle of your activity. Your activity may be destroyed, but static fields survive.

+1
source

If count [] and m_Starbucks [] are still available, then that means PracticeActivity and G are both alive too.

No. count and m_Starbucks are declared static. Per Java Documentation :

"Class variables (static fields) A class variable is any declared field with a static modifier; this tells the compiler that there is exactly one copy of this variable exists, no matter how many times the class has been created"

So, say you do the following: (pretend that this is not an activity, and you can just build it) ...

 PracticeActivity example1 = new PracticeActivity(); PracticeActivity example2 = new PracticeActivity(); 

Then you do not have examples1.m_Starbucks [0] and example2.m_Starbucks [0] as different variables. Instead, you simply have PracticeActivity.m_Starbucks [0], and any particular instance of this class has the same variable. Therefore, it is not affected (not related to!) The destruction of the actual instance of your activity. And in fact, they exist even if you never created an instance of a class that contains them.

Also, if you change example1.m_Starbucks [0], you will see that example2.m_Starbucks [0] has also changed - because, again, there is only one array.

The simple answer here is that you should not use static variables for this type of storage. It is safe to use static for constants and some other special cases, but never as member variables that you expect to store attributes of a given instance of a class that make this instance uniquely different from other classes.

0
source

Source: https://habr.com/ru/post/1342245/


All Articles