关于活动生命周期和资源删除/分配的问题

时间:2011-03-04 06:57:38

标签: android

我对这个生命周期的事情感到非常困惑,所以我做了一些经验。简而言之:结果显示,当一个进程在被销毁之后被创建时,在上一个会话中分配的UI对象都已经消失,需要重新创建(这是预期的)。但是在上一个会话中分配的其他内存空间仍可用于此会话。

令我惊讶的是:系统的UI对象(如ListView)和我分配的内存空间不会同时被破坏。为什么他们不同时死亡(或活着)?

请参阅此处的体验:

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"
    };
}

这是G类,在G.java文件中定义:

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

运行此测试会产生以下结果:

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

在第一个会话中,count [99]的值为0,因此程序将填充ListView,所以一切都很好。

在第二个会话中,count [99]仍保留第一个会话剩余的值,因此程序没有填充ListView,希望ListView也可用。但事实并非如此,结果是黑屏。这意味着G.count []在上一次会话中被保留(m_Starbucks []也是如此),但ListView没有存活。

很明显系统中只有一个PracticeActivity实例,当这个实例消亡时,PracticeActivity和G类都应该死掉。但他们没有,他们仍保留上一届会议的价值观。

问题:

  1. 如果count []和m_Starbucks []是 仍然可用,那么这意味着 PracticeActivity和G都是 还活着。然后是ListView的原因 到哪里去了?不应该全部死亡或 住在同一时间?
  2. 当我看到某些的课程时 成员持有他们的旧价值观 上次会议,我能相信吗? 所有我班级的成员也有效???即,Android 在一个全有或全无的情况下杀死我的资源 时尚?或者,它可以删除一些和 离开其他人? (这个问题 不应该存在于第一个 地方,但看到了结果 经验,人们开始怀疑。)
  3. 有人可以对此有所了解吗?非常感谢。

2 个答案:

答案 0 :(得分:1)

只要JVM(DVM)存在,静态类成员就会活着 - 这可能(当然也可能)长于 你的活动生命周期。您的活动可能会被破坏,但静态字段会在其中存活。

答案 1 :(得分:0)

  

如果count []和m_Starbucks []仍然存在   可用,那么这意味着   PracticeActivity和G都活着   太

没有。 count和m_Starbucks都被声明为静态。每Java documentation

  

“类变量(静态字段)A   class变量是声明的任何字段   使用静态修饰符;这说明了   编译器中只有一个   这个变量的副本存在,   无论班级多少次   已被实例化“

所以说你做了以下事情:(假装这不是一个活动,你可以方便地构建它)......

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

然后你将example1.m_Starbucks [0]和example2.m_Starbucks [0]作为不同的变量。相反,您只需拥有PracticeActivity.m_Starbucks [0],该类的任何特定实例都具有相同的变量。因此,它不受(与!无关)对Activity的实际实例的破坏的影响。事实上,即使你有从不构建包含它们的类的实例,它们也存在

另外,如果你改变example1.m_Starbucks [0],你会发现example2.m_Starbucks [0]也发生了变化 - 因为,同样只有一个数组。

这里的简单答案是你不应该为这种类型的存储使用静态变量。对常量和其他一些特殊情况使用static是安全的,但是从不作为你希望保存给定类实例的属性的成员变量,这使得该实例与其他类唯一不同。