2011年12月19日 星期一

Android - activity : launchMode(1) - standard介紹

我將分成4篇文章來討論在activity的android:launchMode,分別為
standard
singleTop
singleTask
singleInstance

請先參考http://developer.android.com/guide/topics/manifest/activity-element.html#lmode

為了進行測試,我寫了一個由3個activity所組成的程式
A1
A2
A3
藉由這3個activity的互相intent呼叫並按下Back Key的方式
來了解不同的launchMode會有什麼影響。所有的範例,僅修改A2的launchMode,程式碼如下:

public class A1 extends Activity {
    /** Called when the activity is first created. */
    private String mString;
    private TextView txt1_history;
    private OnClickListener mListener;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        TextView txt1 = (TextView) findViewById(R.id.TextView1_intent);
        txt1.setText(txt1.getText() + getIntent().getStringExtra("intent"));

        txt1_history = (TextView) findViewById(R.id.TextView1_history);

        Button button1_2 = (Button) findViewById(R.id.Button1_2);
        Button button1_3 = (Button) findViewById(R.id.Button1_3);

        mListener = new OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent();
                if (v.getId() == R.id.Button1_2) {
                    intent.setClass(A1.this, A2.class);
                } else if (v.getId() == R.id.Button1_3) {
                    intent.setClass(A1.this, A3.class);
                }
                intent.putExtra("intent", "Intent1");
                intent.putExtra("history", mString);
                startActivity(intent);
            }
        };

        button1_2.setOnClickListener(mListener);
        button1_3.setOnClickListener(mListener);

    }

    @Override
    public void onResume() {
        super.onResume();
        mString = getIntent().getStringExtra("history");
        if (mString == null) {
            mString = "";
        }
        txt1_history.setText(mString + this.toString() + "  -->  \n");
        mString = (String) txt1_history.getText();
    }
}

public class A2 extends Activity {
    private String mString;
    private TextView txt2_history;
    private OnClickListener mListener;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main2);

        TextView txt2 = (TextView) findViewById(R.id.TextView2_intent);
        txt2.setText(txt2.getText() + getIntent().getStringExtra("intent"));

        txt2_history = (TextView) findViewById(R.id.TextView2_history);

        Button button2_1 = (Button) findViewById(R.id.Button2_1);
        Button button2_2 = (Button) findViewById(R.id.Button2_2);
        Button button2_3 = (Button) findViewById(R.id.Button2_3);

        mListener = new OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent();
                if (v.getId() == R.id.Button2_1) {
                    intent.setClass(A2.this, A1.class);
                } else if (v.getId() == R.id.Button2_2) {
                    intent.setClass(A2.this, A2.class);
                } else if (v.getId() == R.id.Button2_3) {
                    intent.setClass(A2.this, A3.class);
                }
                intent.putExtra("intent", "Intent2");
                intent.putExtra("history", mString);
                startActivity(intent);
            }
        };

        button2_1.setOnClickListener(mListener);
        button2_2.setOnClickListener(mListener);
        button2_3.setOnClickListener(mListener);
    }

    @Override
    public void onResume() {
        super.onResume();
        mString = getIntent().getStringExtra("history");
        if (mString == null) {
            mString = "";
        }
        txt2_history.setText(mString + this.toString() + "  -->  \n");
        mString = (String) txt2_history.getText();
    }
}

public class A3 extends Activity {
    private String mString;
    private TextView txt3_history;
    private OnClickListener mListener;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main3);

        TextView txt3 = (TextView) findViewById(R.id.TextView3_intent);
        txt3.setText(txt3.getText() + getIntent().getStringExtra("intent"));

        txt3_history = (TextView) findViewById(R.id.TextView3_history);

        Button button3_1 = (Button) findViewById(R.id.Button3_1);
        Button button3_2 = (Button) findViewById(R.id.Button3_2);

        mListener = new OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent();
                if (v.getId() == R.id.Button3_1) {
                    intent.setClass(A3.this, A1.class);
                } else if (v.getId() == R.id.Button3_2) {
                    intent.setClass(A3.this, A2.class);
                }
                intent.putExtra("intent", "Intent3");
                intent.putExtra("history", mString);
                startActivity(intent);
            }
        };

        button3_1.setOnClickListener(mListener);
        button3_2.setOnClickListener(mListener);
    }

    @Override
    public void onResume() {
        super.onResume();
        mString = getIntent().getStringExtra("history");
        if (mString == null) {
            mString = "";
        }
        txt3_history.setText(mString + this.toString() + "  -->  \n");
        mString = (String) txt3_history.getText();
    }
}

最後是AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.testintent" android:versionCode="1" android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <activity android:name=".A1" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".A2" android:label="@string/app_name" />

        <activity android:name=".A3" android:label="@string/app_name" />

    </application>
</manifest>

現在先討論standard的模式。
在Mainfest.xml中對activity中的A2不指定任何launchMode,或是修改為
        <activity android:name=".A2" android:label="@string/app_name" android:launchMode="standard"/>
都表示A2都是使用standard的方式。


程式執行後,呼叫activity的順序為A1->A2->A2->A2->A3,一開始到最後結果如下
程式一開始執行時




















由A1按下「Intent to A2」Button時



















由A2按下「Intent to A2」Button






































最後一次由A2到A3所產生的畫面




















請注意,A2被按了3次,也實際上產生了3個實體instance,可以看到
com.testintent.A2@43e4a208
com.testintent.A2@43e528d8
com.testintent.A2@43e5aac8
分別是3個不同的hashcode

現在試著從A3,一直按下Back Key,可以發現到activity消失的順序為
A3 -> A2 -> A2 -> A2 -> A1

其中A2消失的順序是
com.testintent.A2@43e5aac8
然後才是
com.testintent.A2@43e528d8
最後是
com.testintent.A2@43e4a208

結論: launchMode是standard,則當startActivity時,都會產生出一個獨立的實體instance並放置在activity stack的上層


沒有留言:

張貼留言