在IntentDemo示例中,通過使用startActivity(Intent)方法啟動(dòng)Activity后,兩個(gè)Activity之間相互獨(dú)立,沒有任何關(guān)聯(lián)。然而,在很多情況下,后啟動(dòng)的Activity是為了讓用戶對(duì)特定信息進(jìn)行選擇,在關(guān)閉這個(gè)Activity后,用戶的選擇信息需要返回給未關(guān)閉的那個(gè)Activity。由此,按照Activity啟動(dòng)的先后順序,先啟動(dòng)的稱為父Activity,后啟動(dòng)的稱為子Activity,如果需要將子Activity的部分信息返回給父Activity,則可以使用Sub-Activity的方式去啟動(dòng)子Activity。
獲取子Activity的返回值,一般分以下3個(gè)步驟。
1.以Sub-Activity的方式啟動(dòng)子Activity
首先,調(diào)用startActivityForResult(Intent, requestCode)函數(shù),其中,參數(shù)Intent用于決定啟動(dòng)哪個(gè)Activity,參數(shù)requestCode是唯一的標(biāo)識(shí)子Activity的請(qǐng)求碼。
顯式啟動(dòng)子Activity的代碼如代碼清單6-11所示。
代碼清單6-11 顯式啟動(dòng)子Activity
int SUBACTIVITY1 = 1;
Intent intent = new Intent(this, SubActivity1.class);
startActivityForResult(intent, SUBACTIVITY1);
隱式啟動(dòng)子Activity的代碼如代碼清單6-12所示。
代碼清單6-12 隱式啟動(dòng)子Activity
int SUBACTIVITY2 = 2;
Uri uri = Uri.parse("content://contacts/people");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
startActivityForResult(intent, SUBACTIVITY2);
2.設(shè)置子Activity的返回值
在子Activity調(diào)用finish()函數(shù)關(guān)閉前,調(diào)用setResult()函數(shù)將所需的數(shù)據(jù)返回給父Activity。其中,setResult()函數(shù)有兩個(gè)參數(shù):結(jié)果碼和返回值。結(jié)果碼表明了子Activity的返回狀態(tài),通常為Activity.RESULT_OK或Activity.RESULT_CANCELED,或自定義的結(jié)果碼,結(jié)果碼均為整數(shù)類型;返回值封裝在Intent中,子Activity通過Intent將需要返回的數(shù)據(jù)傳遞給父Activity。數(shù)據(jù)主要是Uri形式,可以附加一些額外信息,這些額外信息用Extra的集合表示。
代碼清單6-13所示代碼說明了如何在子Activity中設(shè)置返回值。
代碼清單6-13 在子Activity中設(shè)置返回值
Uri data = Uri.parse(“tel:” + tel_number);
Intent result = new Intent(null, data);
result.putExtra(“address”, “ “);
setResult(RESULT_OK, result);
finish();
3.在父Activity中獲取返回值
當(dāng)子Activity關(guān)閉時(shí),啟動(dòng)它的父Activity的onActivityResult()函數(shù)將被調(diào)用;如果需要在父Activity中處理子Activity的返回值,則覆蓋此函數(shù)即可。此函數(shù)的語法如代碼清單6-14所示。
代碼清單6-14 onActivityResult()語法
public void onActivityResult(int requestCode, int resultCode, Intent data);
在上述代碼中,第1個(gè)參數(shù)requestCode,用來表示是哪一個(gè)子Activity的返回值;第2個(gè)參數(shù)resultCode用于表示子Activity的返回狀態(tài);第3個(gè)參數(shù)data是子Activity的返回?cái)?shù)據(jù),返回?cái)?shù)據(jù)類型是Intent。返回?cái)?shù)據(jù)的用途不同,Uri數(shù)據(jù)的協(xié)議也就不同。也可以使用Extra方法返回一些原始類型的數(shù)據(jù)。
代碼清單6-15所示代碼說明如何在父Activity中處理子Activity的返回值。
代碼清單6-15 在父Activity中處理子Activity的返回值
private static final int SUBACTIVITY1 = 1;
private static final int SUBACTIVITY2 = 2;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
Super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case SUBACTIVITY1:
if (resultCode == Activity.RESULT_OK){
Uri uriData = data.getData();
}else if (resultCode == Activity.RESULT_CANCEL){
}
break;
case SUBACTIVITY2:
if (resultCode == Activity.RESULT_OK){
Uri uriData = data.getData();
}
break;
}
}
在上述代碼中,第1行代碼和第2行代碼是兩個(gè)子Activity的請(qǐng)求碼;第7行代碼對(duì)請(qǐng)求碼進(jìn)行匹配;第9行和第11行代碼對(duì)結(jié)果碼進(jìn)行判斷,如果返回的結(jié)果碼是Activity.RESULT_OK,則在代碼的第10行使用getData()函數(shù)獲取Intent中的Uri數(shù)據(jù);反之,若返回的結(jié)果碼是Activity.RESULT_CANCELED,則不進(jìn)行任何操作。
ActivityCommunication示例說明了如何以Sub-Activity方式啟動(dòng)子Activity,以及使用Intent進(jìn)行組件間的通信。

圖6-4 ActivityCommunication主界面
在如圖6-4所示的主界面中,當(dāng)用戶單擊“啟動(dòng)Activity1”和“啟動(dòng)Activity2”按鈕時(shí),程序?qū)⒎謩e啟動(dòng)兩個(gè)不同的子Activity:子SubActivity1和SubActivity2,它們的界面分別如圖6-5所示。

圖6-5 SubActivity1和SubActivity2界面
SubActivity1提供了一個(gè)輸入框,以及“接受”和“撤銷”兩個(gè)按鈕,如果在輸入框中輸入信息后單擊“接受”按鈕,程序會(huì)把輸入框中的信息傳遞給父Activity,并在父Activity界面上顯示;如果用戶單擊“撤銷”按鈕,則程序不會(huì)向父Activity傳遞任何信息。
SubActivity2主要為了說明如何在父Activity中處理多個(gè)子Activity,因此僅提供了用于關(guān)閉SubActivity2的“關(guān)閉”按鈕。
下面介紹ActivityCommunication的核心代碼。
首先是ActivityCommunication.java文件,如代碼清單6-16所示。
代碼清單6-16 ActivityCommunication.java
public class ActivityCommunication extends Activity {
private static final int SUBACTIVITY1 = 1;
private static final int SUBACTIVITY2 = 2;
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView)findViewById(R.id.textShow);
final Button btn1 = (Button)findViewById(R.id.btn1);
final Button btn2 = (Button)findViewById(R.id.btn2);
btn1.setOnClickListener(new OnClickListener(){
public void onClick(View view){
Intent intent = new Intent(ActivityCommunication.this, SubActivity1.class);
startActivityForResult(intent, SUBACTIVITY1);
}
});
btn2.setOnClickListener(new OnClickListener(){
public void onClick(View view){
Intent intent = new Intent(ActivityCommunication.this, SubActivity2.class);
startActivityForResult(intent, SUBACTIVITY2);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case SUBACTIVITY1:
if (resultCode == RESULT_OK){
Uri uriData = data.getData();
textView.setText(uriData.toString());
}
break;
case SUBACTIVITY2:
break;
}
}
}
在上述代碼中,第2行和第3行分別定義了兩個(gè)子Activity的請(qǐng)求碼,而在第16行和第23行以Sub-Activity的方式分別啟動(dòng)兩個(gè)子Activity。
第29行代碼是子Activity關(guān)閉后的返回值處理函數(shù),其中requestCode是子Activity返回的請(qǐng)求碼,應(yīng)與第2行和第3行定義的兩個(gè)請(qǐng)求碼相匹配;resultCode是結(jié)果碼,在第32行代碼對(duì)結(jié)果碼進(jìn)行判斷,如果等于RESULT_OK,則在第35行代碼獲取子Activity的返回值中的數(shù)據(jù),其中,data是返回值,子Activity需要返回的數(shù)據(jù)就保存在data中。
SubActivity1.java的核心代碼如代碼清單6-17所示。
代碼清單6-17 SubActivity1.java
public class SubActivity1 extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.subactivity1);
final EditText editText = (EditText)findViewById(R.id.edit);
Button btnOK = (Button)findViewById(R.id.btn_ok);
Button btnCancel = (Button)findViewById(R.id.btn_cancel);
btnOK.setOnClickListener(new OnClickListener(){
public void onClick(View view){
String uriString = EditText.getText().toString();
Uri data = Uri.parse(uriString);
Intent result = new Intent(null, data);
setResult(RESULT_OK, result);
finish();
}
});
btnCancel.setOnClickListener(new OnClickListener(){
public void onClick(View view){
setResult(RESULT_CANCELED, null);
finish();
}
});
}
}
上述SubActivity1.java的核心代碼中,第13行代碼將EditText控件的內(nèi)容作為數(shù)據(jù)保存在Uri中;第14行代碼中使用這個(gè)Uri構(gòu)造Intent;第15行代碼中,將Intent作為返回值,RESUIT_OK作為結(jié)果碼,通過調(diào)用setResult()函數(shù),將返回值和結(jié)果碼傳遞給父Activity;第16行代碼調(diào)用finish()函數(shù)關(guān)閉當(dāng)前的子Activity。
SubActivity2.java的核心代碼如代碼清單6-18所示。
代碼清單6-18 SubActivity2.java
public class SubActivity2 extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.subactivity2);
Button btnReturn = (Button)findViewById(R.id.btn_return);
btnReturn.setOnClickListener(new OnClickListener(){
public void onClick(View view){
setResult(RESULT_CANCELED, null);
finish();
}
});
}
}
上述SubActivity2.java的核心代碼中,第10行的setResult()函數(shù)僅設(shè)置了結(jié)果碼,第2個(gè)參數(shù)為null,表示數(shù)據(jù)需要傳遞給父Activity。