1.startActivityForResult的使用场景是什么,onActivityResult回调里面的resultCode和requestCode的含义是什么?
2.Activity A启动B的时候,在B中何时该执行setResult?setResult可以位于Activity的finish方法之后么?
问题1:
startActivityForResult的使用场景:
如果想在ActivityA中得到新打开ActivityB关闭后返回的数据,就需要使用startActivityForResulr(Intent intent,int requestCode)方法打开新的Activity,新的Activity关闭后会向前面的Activity传回数据,在前面的Activity重写onActivity(int requestCode,int resultCode,Intent data)方法即可得到数据。具体是:选择照片。选择联系人,进行数据编辑工作等等。
具体使用如下:
1.首先在之前界面调用startActivityForResult();来跳转界面
public class MainActivity extends Activity {
private final static String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.button_click);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//其中第二个参数是根据业务自行定义
startActivityForResult(new Intent(MainActivity.this,OtherActivity.class),5);
}
});
}
//为了得到新界面回传的数据,必须重写重写onActivityResult方法
/**
* requestCode 请求码 调用startActivityForResult()传递的值
* resultcode 结果码 用于标识是哪个Activity返回的
*
*
*/
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
String result = data.getExtras().getString("result_back");//得到新Activity 关闭后返回的数据
Log.i(TAG, result);
}
}
当所要跳转的Activity关闭后,所要跳转的Activity返回的数据通过Intent进行传递,然后android会调用前面Activity的onActivityResult()方法把存放返回数据的intent作为第三个参数传入。在onActivityResult()方法使用第三个输入参数可以取出新Activity返回的数据
2.在所要跳转的Activity,关闭之前向前面的activity返回数据需要使用系统提供的setResult(int resultCode,Intent data)方法实现
public class OtherActivity extends Activity {
private Button btn_setresult;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
btn_setresult = (Button)findViewById(R.id.btn_setresult);
btn_setresult.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
//把返回数据存入Intent
intent.putExtra("result_back", "My name is luguian");
//设置返回的数据
OtherActivity.this.setResult(5,intent);
//关闭页面返回
OtherActivity.this.finish();
}
});
}
}
结果如下:
可以看出数据会传到原来的界面。
requestCode的含义:
这个主要解决【区分多个异步任务】的问题,与其他异步API的设计类似,如果没有这个信息,那么Activity在收到响应时会进入混乱状态,比如不知道自己得到的是选择图片还是选择地址等等的结果。请求码的值是根据自己的业务来定义,请求码必须大于=0 因为只有非负数时新的ActivityRecoed对象的resultTo变量才指向发起者ActivityRecord对象。总而言之:就是区分标识请求来源。
具体使用例子:
@Override public void onCreate(Bundle savedInstanceState) {
....
text1.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 5);
}
});
text2.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
startActivityForResult (new Intent(MainActivity.this, NewActivity.class),6);
}
});
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode){
case 5:
//来自文本1的请求,作相应业务处理
case 6:
//来自文本2的请求,作相应业务处理
}
}
}
resultCode的含义
异步调用结果码,告诉调用者成功/失败/其他信息 -- 该信息由被调用Activity/framework写入,经过AMS传递给源码。也可以根据resultCode来知道是哪个activity返回。具体使用如下:
public class OtheroneActivity extends Activity {
.....
OtheroneActivity.this.setResult(1, intent);
OtheroneActivity.this.finish();
}
public class OthertwoActivity extends Activity {
......
OthertwoActivity.this.setResult(2, intent);
OthertwoActivity.this.finish();
}
public class MainActivity extends Activity { // 在该Activity会打开OtheroneActivity和OthertwoActivity
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(resultCode){
case 1:
// OtherOneActivity的返回数据
case 2:
// OthertwoActivity的返回数据
}
}
}
2.Activity A启动B的时候,在B中何时该执行setResult?setResult可以位于Activity的finish方法之后么?
在onCreate.onStart,onResume调用setResult,都能在上一个Activity中回调onActivityResult,获取结果。
但是如果在onPause,onstop,onDestroy中调用setResult,回调onActivityResult的resultCode为RESULT_CANCELED(0),并且附带的resultData == null,原因是调用finish的时候会将resultCode和resultData通过ActivityManagerService传递出去,因此回调onPause,onStop,onDestroy的时候再执行setResult就没有什么作用了。
源码分析:
finish:
private void finish(int finishTask) {
if (mParent == null) {
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (false) Log.v(TAG, "Finishing self: token=" + mToken);
try {
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
if (ActivityManager.getService()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
}
setResult:
public final void setResult(int resultCode, Intent data) {
synchronized (this) {
mResultCode = resultCode;
mResultData = data;
}
}
也就是说finish后,resultcode置为0,resultData置为null,所以setResult不可以位于Activity的finish方法之后调用,会没有结果,无法将结果返回。