在IntentDemo示例中,通过使用startActivity(Intent)方法启动Activity后,两个Activity之间相互独立,没有任何关联。然而,在很多情况下,后启动的Activity是为了让用户对特定信息进行选择,在关闭这个Activity后,用户的选择信息需要返回给未关闭的那个Activity。由此,按照Activity启动的先后顺序,先启动的称为父Activity,后启动的称为子Activity,如果需要将子Activity的部分信息返回给父Activity,则可以使用Sub-Activity的方式去启动子Activity。
获取子Activity的返回值,一般分以下3个步骤。
1.以Sub-Activity的方式启动子Activity
首先,调用startActivityForResult(Intent, requestCode)函数,其中,参数Intent用于决定启动哪个Activity,参数requestCode是唯一的标识子Activity的请求码。
显式启动子Activity的代码如代码清单6-11所示。
代码清单6-11 显式启动子Activity
int SUBACTIVITY1 = 1;
Intent intent = new Intent(this, SubActivity1.class);
startActivityForResult(intent, SUBACTIVITY1);
隐式启动子Activity的代码如代码清单6-12所示。
代码清单6-12 隐式启动子Activity
int SUBACTIVITY2 = 2;
Uri uri = Uri.parse("content://contacts/people");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
startActivityForResult(intent, SUBACTIVITY2);
2.设置子Activity的返回值
在子Activity调用finish()函数关闭前,调用setResult()函数将所需的数据返回给父Activity。其中,setResult()函数有两个参数:结果码和返回值。结果码表明了子Activity的返回状态,通常为Activity.RESULT_OK或Activity.RESULT_CANCELED,或自定义的结果码,结果码均为整数类型;返回值封装在Intent中,子Activity通过Intent将需要返回的数据传递给父Activity。数据主要是Uri形式,可以附加一些额外信息,这些额外信息用Extra的集合表示。
代码清单6-13所示代码说明了如何在子Activity中设置返回值。
代码清单6-13 在子Activity中设置返回值
Uri data = Uri.parse(“tel:” + tel_number);
Intent result = new Intent(null, data);
result.putExtra(“address”, “ “);
setResult(RESULT_OK, result);
finish();
3.在父Activity中获取返回值
当子Activity关闭时,启动它的父Activity的onActivityResult()函数将被调用;如果需要在父Activity中处理子Activity的返回值,则覆盖此函数即可。此函数的语法如代码清单6-14所示。
代码清单6-14 onActivityResult()语法
public void onActivityResult(int requestCode, int resultCode, Intent data);
在上述代码中,第1个参数requestCode,用来表示是哪一个子Activity的返回值;第2个参数resultCode用于表示子Activity的返回状态;第3个参数data是子Activity的返回数据,返回数据类型是Intent。返回数据的用途不同,Uri数据的协议也就不同。也可以使用Extra方法返回一些原始类型的数据。
代码清单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行代码是两个子Activity的请求码;第7行代码对请求码进行匹配;第9行和第11行代码对结果码进行判断,如果返回的结果码是Activity.RESULT_OK,则在代码的第10行使用getData()函数获取Intent中的Uri数据;反之,若返回的结果码是Activity.RESULT_CANCELED,则不进行任何操作。
ActivityCommunication示例说明了如何以Sub-Activity方式启动子Activity,以及使用Intent进行组件间的通信。

图6-4 ActivityCommunication主界面
在如图6-4所示的主界面中,当用户单击“启动Activity1”和“启动Activity2”按钮时,程序将分别启动两个不同的子Activity:子SubActivity1和SubActivity2,它们的界面分别如图6-5所示。

图6-5 SubActivity1和SubActivity2界面
SubActivity1提供了一个输入框,以及“接受”和“撤销”两个按钮,如果在输入框中输入信息后单击“接受”按钮,程序会把输入框中的信息传递给父Activity,并在父Activity界面上显示;如果用户单击“撤销”按钮,则程序不会向父Activity传递任何信息。
SubActivity2主要为了说明如何在父Activity中处理多个子Activity,因此仅提供了用于关闭SubActivity2的“关闭”按钮。
下面介绍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行分别定义了两个子Activity的请求码,而在第16行和第23行以Sub-Activity的方式分别启动两个子Activity。
第29行代码是子Activity关闭后的返回值处理函数,其中requestCode是子Activity返回的请求码,应与第2行和第3行定义的两个请求码相匹配;resultCode是结果码,在第32行代码对结果码进行判断,如果等于RESULT_OK,则在第35行代码获取子Activity的返回值中的数据,其中,data是返回值,子Activity需要返回的数据就保存在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控件的内容作为数据保存在Uri中;第14行代码中使用这个Uri构造Intent;第15行代码中,将Intent作为返回值,RESUIT_OK作为结果码,通过调用setResult()函数,将返回值和结果码传递给父Activity;第16行代码调用finish()函数关闭当前的子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()函数仅设置了结果码,第2个参数为null,表示数据需要传递给父Activity。