浅谈Android中的startActivityForResult和setResult方法
引言
我们知道,如果想打开一个新的Activity我们可以使用startActivity方法。今天我们介绍的startActivityForResult不仅可以打开全新的Activity,而且当新的Activity关闭后,父Activity可以接收到新窗口设置的值。这篇文章我们就来介绍下startActivityForResult和setResult这两个方法。下面来看例子吧。
实例
startActivityForResult方法
我们来看一个简单的例子。这个例子的MainActivity上有两个按钮,点击这两个按钮都会打开一个全新的界面SecodeActivity,SecodeActivity在退出时会向MainActivity传递数据。我们首先来看下MainActivity的代码:
- package com.example.dreamgong.apprunresearch;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- private Button mButton1;
- private Button mButton2;
- private static final int REQUESTCODE1=0x0001;
- private static final int REQUESTCODE2=0x0002;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initControl();
- }
- private void initControl() {
- mButton1=(Button)findViewById(R.id.button);
- mButton1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
- intent.putExtra("KEY1", "BTN1MSG1");
- //打开新的Activity并且接受Activity的返回值
- startActivityForResult(intent, REQUESTCODE1);
- }
- });
- mButton2=(Button)findViewById(R.id.button2);
- mButton2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
- intent.putExtra("KEY1", "BTN2MSG2");
- //打开新的Activity并且接受Activity的返回值
- startActivityForResult(intent, REQUESTCODE2);
- }
- });
- }
- /**
- * 当新打开的界面退出,处理返回的数据
- * @param requestCode
- * @param resultCode
- * @param data
- */
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if(resultCode==Activity.RESULT_OK) {
- if(requestCode==REQUESTCODE1){
- String msg=data.getStringExtra("Second");
- msg+="这是第一个按钮点击跳转的";
- Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
- }
- if(requestCode==REQUESTCODE2){
- String msg=data.getStringExtra("Second");
- msg+="这是第二个按钮点击跳转的";
- Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
- }
- }
- }
- }
在代码中我们看到initControl方法主要负责初始化控件以及设置点击事件。我们看到两个按钮都设置了事件处理函数,都是跳转到SecondActivity。只是传递给SecondActivity界面的值不一致。我们也看到startActivityForResult方法的第二个参数是int类型的,需要传递RequestCode。
RequestCode的作用:
RequestCode的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这两个按钮都会打开同一个Activity,不管是那个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由那个按钮打开的。我们看到在onActivityResult方法中我们就是通过RequestCode来区分是哪一个按钮打开了新的界面,我们可以编写相应的业务代码。
setResult方法
下面我们来看SecondActivity中的逻辑代码,我们知道SecondActivity方法在关闭时需要向MainActivity方法中传递数据。怎么传递呢?我们结合Activity的生命周期来探究。
我们先来看SecondActivity退出,MainActivity重新呈现时,这一流程方法的调用过程。B代表新打开的SecondActivity,A表示MainActivity。整个过程如下:
B---onPause
A---onActivityResult
A---onRestart
A---onStart
A---onResume
B---onStop
B---onDestroy
从上面过程可以看出,首先是B处于Pause 状态,然后等待A执行 onRestart——> onStart ——〉onResume,然后才是B 的onStop——>onDestroy,而A的 onActivityResult() 需要在B的onPause之后,A的onRestart之前这中间调用,所以B中的setResult()函数应该放在B的onPause之前调用。
另外我试验了一下,如果把setResult()放在 B 的 onPause() 里面调用,结果仍然是无效的。
那么setResult()应该在什么时候调用呢?从源码可以看出,Activity返回result是在被finish的时候,也就是说调用setResult()方法必须在finish()之前。所以在onPause、onStop、onDestroy方法中调用setResult()也有可能不会返回成功,因为这些方法调用不一定是在finish之前的。我们来详细看下源码:
setResult()方法的源码:
- public final void setResult(int resultCode, Intent data) {
- synchronized (this) {
- mResultCode = resultCode;
- mResultData = data;
- }
- }
finish()方法的源码:
- 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);
- }
- }
看代码的6,7行mResultCode是必须先经过setResult方法进行赋值的。所以setResult方法必须在finish方法之前调用!!!
实际应用场景
在实际使用中我们使用setResult方法一般都借助onBackPressed()方法或者点击事件。看下面的例子:
1、按Back键(回退键):
按BACK键从一个Activity退出来的,一按BACK,android就会自动调用Activity的finish()方法,方法:重写onBackPressed()方法,捕获BACK事件,捕获到之后先setResult。代码如下:
- @Override
- public void onBackPressed() {
- Intent intent=new Intent();
- intent.putExtra("Second","HELLO WORLD!!!");
- setResult(Activity.RESULT_OK,intent);
- finish();
- super.onBackPressed();
- }
2、按点击事件中显式的调用finish()
这时候整个执行流程如下:
B---onBackPressed
B---finish
B---onPause
A---onActivityResult
A---onRestart
A---onStart
A---onResume
B---onStop
B---onDestroy
浅谈Android中的startActivityForResult和setResult方法的更多相关文章
- 浅谈Android中拍照、从相册选择图片并截图相关知识点
前言 我们在Android开发中经常会需要使用相机或者从相册中选取图片的情况,今天就把这里面相关的知识点总结下,方便以后开发的时候使用. 1.相机拍照并可自定义截图功能 我们先来看如何使用Intent ...
- 浅谈Android中Serializable和Parcelable使用区别
版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.概述 Android开发的时候,我们时长遇到传递对象的需求,但是我们无法将对象的引用传给Activity或者Fragment,我们需要将这些对象 ...
- 浅谈android中只使用一个TextView实现高仿京东,淘宝各种倒计时
今天给大家带来的是只使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.近期公司一直加班也没来得及时间去整理,今天难得歇息想把这个分享给大家.只求共同学习,以及自己兴许 ...
- 浅谈android中的目录结构
之前在android游戏开发中就遇到本地数据存储的问题:一般情形之下就将动态数据写入SD中存储,在没有SD卡的手机上就需另作处理了;再有在开发android应用的过程中,总要去调试APP,安装时又想去 ...
- 浅谈Android中layout_weight
引言 在开发android过程中,我们经常需要对界面进行按比例进行布局,我们一般都会使用layout_属性来进行设置.今天这篇文章我们就来简单介绍下layout_weight的使用和布局原理.随着做项 ...
- 浅谈Android中Activity的生命周期
引言 我想对于Android开发人员来说,Activity是再熟悉不过了,今天我们就来探讨下Activity的生命周期.熟悉的掌握Activity对于开发健壮的Android应用程序来说至关重要.下面 ...
- 浅谈Android中的事件分发机制
View事件分发机制的本质就是就是MotionEvent事件的分发过程,即MotionEvent产生后是怎样在View之间传递及处理的. 首先介绍一下什么是MotionEvent.所谓MotionEv ...
- 浅谈Android中的组播(多播)
组播使用UDP对一定范围内的地址发送相同的一组Packet,即一次可以向多个接受者发出信息,其与单播的主要区别是地址的形式.IP协议分配了一定范围的地址空间给多播(多播只能使用这个范围内的IP),IP ...
- Android中的onActivityResult和setResult方法的使用
如果你想在Activity中得到新打开Activity关闭后返回的数据,你需要使用系统提供的startActivityForResult(Intent intent,int requestCode)方 ...
随机推荐
- linux 排序命令sort
sort [选项] [文件] 选项: -b:忽略每行前面开始出的空格字符: -c:检查文件是否已经按照顺序排序: -d:排序时,处理英文字母.数字及空格字符外,忽略其他的字符: -f:排序时,将小写字 ...
- 谈谈Redis的SETNX
谈谈Redis的SETNX 发表于2015-09-14 在 Redis 里,所谓 SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果,不 ...
- [WPF系列]-数据邦定之DataTemplate 根据对象属性切换模板
引言 书接上回[WPF系列-数据邦定之DataTemplate],本篇介绍如何根据属性切换模板(DataTemplate) 切换模板的两种方式: 使用DataTemplateSelecto ...
- PhotoShop算法原理解析系列 - 风格化---》查找边缘。
之所以不写系列文章一.系列文章二这样的标题,是因为我不知道我能坚持多久.我知道我对事情的表达能力和语言的丰富性方面的天赋不高.而一段代码需要我去用心的把他从基本原理-->初步实现-->优化 ...
- SQL高级查询:嵌套和分页
1.嵌套子查询 --查询最近一次oop考试没有参加考试的学生 select StudentName from Student where StudentNo not in( select Studen ...
- HiKariCP的数据源配置
<!-- Hikari Datasource --> <bean id="dataSourceHikari" class="com.zaxxer.hik ...
- 再谈Newtonsoft.Json高级用法
上一篇Newtonsoft.Json高级用法发布以后收到挺多回复的,本篇将分享几点挺有用的知识点和最近项目中用到的一个新点进行说明,做为对上篇文章的补充. 阅读目录 动态改变属性序列化名称 枚举值序列 ...
- 淘宝WAP版小BUG分析
前几天发现的一个淘宝WAP版的小BUG,就是用桌面版chrome看的时候产品评价中的图片显示不出来,都是图裂了. 这是什么原因呢?图片为什么会显示不出来呢?淘宝的技术人员.测试人员不可能没发现啊.开启 ...
- cookie学习指南
一.什么是cookie cookie也叫HTTP cookie,最初是用来客户端和服务器端进行会话用的,由于HTTP是一种无状态的协议,为了维持用户和跟踪用户信息,所以引入了cookie和sessio ...
- 对.net技术组件的分析和选择
.net很庞杂,学习最忌讳什么?为了学而学,而不是为了用而学.我们不是为了成为教师,所以不要成为书呆子,不要成为"博士",要从庞杂的技术群中选择自己需要的内容进行学习. 如果不加选 ...