专题4:startActivityForResult

在这里插入图片描述
startActivityForResult(Intent intent, int requestCode)这个方法一般用来在ActivityA中启动另个activityB,当返回的时候需要携带来自B的数据更新ActivityA界面。

一.首先在ActivityA中启动startActivityForResult startActivityForResult(Intent intent, int requestCode)
在这里插入图片描述
参数1.intent,可以携带一些数据。
参数2.requesCode,自定义的一个int类型的数值(一般>0),当从activityB中返回来的时候会一起回传,所以可以用这个参数来判断是从哪个activity中返回的。(注意:开启新的activity时传递的requestCode必须不一样,才能保证数据回传正常)

源码中,在activity的启动过程中,通过ActivityStackSupervisor的startActivityLocked方法中的ActivityRecord对象将requesCode信息保存。

二.其次还有一个方法。这个方法是在ActivityB中使用的,主要一定要在finish()之前调用该方法不然不起作用
setResult(int resultCode, Intent data)

在这里插入图片描述
同样还是两个参数:
参数1:resultcode,这个参数有两个作用:1.判断有没有返回成功。2.可以判断是从哪个activity返回。
为什么呢?这个参数可以自定义,如果返回成功了,之前在activityB中定义的resultcode和在ActivityA中onActivityResult(int requestCode, int resultCode, Intent data)方法中获取的resultcode的值一样,因此可以通过resultcode来判断当前activity从哪个activity返回。 如果失败了(比如你在ActivityB中直接按了返回键,什么都没有操作),这种情况在ActivityA中接收到的requestCode就是0,所以这个参数可以用来判断是否返回成功。
参数2:Intent data,不同Activity之前传递数据。

setResult必须在finish之前进行调用,查看源码,发现在setResult中将resultCode和data进行数据存储。
public final void setResult(int resultCode, Intent data) {
synchronized (this) {
mResultCode = resultCode;
mResultData = data;
}
}
后续在调用finish时,获取resultCode和data值并通过AMS的finishActivity传递出去。
private void finish(boolean 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();
}
if (ActivityManagerNative.getDefault()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
}
最终在ActivityRecord类中,将resultCode和data保存到ActivityResult对象中,再将ActivityResult对象存储到results列表中,等待后续ActivityB退出ActivityA启动时调用。

三。最后在ActivityA中onActivityResult()中接收数据,然后拿到数据进行逻辑处理或页面更新。
在这里插入图片描述
**注意:当ActivityB为singleTask或者singleInstance时,ActivityA执行startActivityForResult之后,在onPause后会立即执行onActivityResult()。**如下图:
在这里插入图片描述
原因:
1.singleInstance,因为跨栈跳转,按返回键后不一定会回到原Activity。

举例:假设栈A存在Activity1,栈B中存在Activitya、Activityb。Activity1跳转到Activitya,按返回键后,Activitya出栈,Activityb出现在栈顶显示在界面上。
在这里插入图片描述
2.singleTask,ActivityA跳转ActivityB,ActivityA不一定在栈内。
如果在执行ActivityA之前,执行过ActivityB,当在ActivityA中执行startActivityForResult时,会将ActivityA移出栈,ActivityA自然无法获取到data数据,因此Android如此设计。

END.
可查看以下微博了解更多详细分析:
http://www.cnblogs.com/cmgrass/p/5088265.html
https://blog.csdn.net/cbzcbzcbzcbz/article/details/76060986

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值