引言

  我们知道,如果想打开一个新的Activity我们可以使用startActivity方法。今天我们介绍的startActivityForResult不仅可以打开全新的Activity,而且当新的Activity关闭后,父Activity可以接收到新窗口设置的值。这篇文章我们就来介绍下startActivityForResult和setResult这两个方法。下面来看例子吧。

实例

  startActivityForResult方法

  我们来看一个简单的例子。这个例子的MainActivity上有两个按钮,点击这两个按钮都会打开一个全新的界面SecodeActivity,SecodeActivity在退出时会向MainActivity传递数据。我们首先来看下MainActivity的代码:

  1. package com.example.dreamgong.apprunresearch;
  2.  
  3. import android.app.Activity;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.widget.Button;
  8. import android.widget.Toast;
  9.  
  10. public class MainActivity extends Activity {
  11.  
  12. private Button mButton1;
  13. private Button mButton2;
  14.  
  15. private static final int REQUESTCODE1=0x0001;
  16. private static final int REQUESTCODE2=0x0002;
  17.  
  18. @Override
  19. protected void onCreate(Bundle savedInstanceState) {
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.activity_main);
  22.  
  23. initControl();
  24. }
  25.  
  26. private void initControl() {
  27. mButton1=(Button)findViewById(R.id.button);
  28. mButton1.setOnClickListener(new View.OnClickListener() {
  29. @Override
  30. public void onClick(View v) {
  31. Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
  32. intent.putExtra("KEY1", "BTN1MSG1");
  33. //打开新的Activity并且接受Activity的返回值
  34. startActivityForResult(intent, REQUESTCODE1);
  35. }
  36. });
  37.  
  38. mButton2=(Button)findViewById(R.id.button2);
  39. mButton2.setOnClickListener(new View.OnClickListener() {
  40. @Override
  41. public void onClick(View v) {
  42. Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
  43. intent.putExtra("KEY1", "BTN2MSG2");
  44. //打开新的Activity并且接受Activity的返回值
  45. startActivityForResult(intent, REQUESTCODE2);
  46. }
  47. });
  48. }
  49.  
  50. /**
  51. * 当新打开的界面退出,处理返回的数据
  52. * @param requestCode
  53. * @param resultCode
  54. * @param data
  55. */
  56.  
  57. @Override
  58. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  59. if(resultCode==Activity.RESULT_OK) {
  60. if(requestCode==REQUESTCODE1){
  61. String msg=data.getStringExtra("Second");
  62. msg+="这是第一个按钮点击跳转的";
  63. Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
  64. }
  65. if(requestCode==REQUESTCODE2){
  66. String msg=data.getStringExtra("Second");
  67. msg+="这是第二个按钮点击跳转的";
  68. Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
  69. }
  70. }
  71. }
  72.  
  73. }

  在代码中我们看到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()方法的源码:

  1. public final void setResult(int resultCode, Intent data) {
  2. synchronized (this) {
  3. mResultCode = resultCode;
  4. mResultData = data;
  5. }
  6. }

  finish()方法的源码:

  1. private void finish(boolean finishTask) {
  2. if (mParent == null) {
  3. int resultCode;
  4. Intent resultData;
  5. synchronized (this) {
  6. resultCode = mResultCode;
  7. resultData = mResultData;
  8. }
  9. if (false) Log.v(TAG, "Finishing self: token=" + mToken);
  10. try {
  11. if (resultData != null) {
  12. resultData.prepareToLeaveProcess();
  13. }
  14. if (ActivityManagerNative.getDefault()
  15. .finishActivity(mToken, resultCode, resultData, finishTask)) {
  16. mFinished = true;
  17. }
  18. } catch (RemoteException e) {
  19. // Empty
  20. }
  21. } else {
  22. mParent.finishFromChild(this);
  23. }
  24. }

  看代码的6,7行mResultCode是必须先经过setResult方法进行赋值的。所以setResult方法必须在finish方法之前调用!!!

  实际应用场景

  在实际使用中我们使用setResult方法一般都借助onBackPressed()方法或者点击事件。看下面的例子:

  1、按Back键(回退键):

  按BACK键从一个Activity退出来的,一按BACK,android就会自动调用Activity的finish()方法,方法:重写onBackPressed()方法,捕获BACK事件,捕获到之后先setResult。代码如下:

  1. @Override
  2. public void onBackPressed() {
  3.  
  4. Intent intent=new Intent();
  5. intent.putExtra("Second","HELLO WORLD!!!");
  6. setResult(Activity.RESULT_OK,intent);
  7. finish();
  8. super.onBackPressed();
  9.  
  10. }

  2、按点击事件中显式的调用finish()

  这时候整个执行流程如下:

  B---onBackPressed
  B---finish
  B---onPause
  A---onActivityResult
  A---onRestart
  A---onStart
  A---onResume
  B---onStop
  B---onDestroy

浅谈Android中的startActivityForResult和setResult方法的更多相关文章

  1. 浅谈Android中拍照、从相册选择图片并截图相关知识点

    前言 我们在Android开发中经常会需要使用相机或者从相册中选取图片的情况,今天就把这里面相关的知识点总结下,方便以后开发的时候使用. 1.相机拍照并可自定义截图功能 我们先来看如何使用Intent ...

  2. 浅谈Android中Serializable和Parcelable使用区别

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.概述 Android开发的时候,我们时长遇到传递对象的需求,但是我们无法将对象的引用传给Activity或者Fragment,我们需要将这些对象 ...

  3. 浅谈android中只使用一个TextView实现高仿京东,淘宝各种倒计时

    今天给大家带来的是只使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.近期公司一直加班也没来得及时间去整理,今天难得歇息想把这个分享给大家.只求共同学习,以及自己兴许 ...

  4. 浅谈android中的目录结构

    之前在android游戏开发中就遇到本地数据存储的问题:一般情形之下就将动态数据写入SD中存储,在没有SD卡的手机上就需另作处理了;再有在开发android应用的过程中,总要去调试APP,安装时又想去 ...

  5. 浅谈Android中layout_weight

    引言 在开发android过程中,我们经常需要对界面进行按比例进行布局,我们一般都会使用layout_属性来进行设置.今天这篇文章我们就来简单介绍下layout_weight的使用和布局原理.随着做项 ...

  6. 浅谈Android中Activity的生命周期

    引言 我想对于Android开发人员来说,Activity是再熟悉不过了,今天我们就来探讨下Activity的生命周期.熟悉的掌握Activity对于开发健壮的Android应用程序来说至关重要.下面 ...

  7. 浅谈Android中的事件分发机制

    View事件分发机制的本质就是就是MotionEvent事件的分发过程,即MotionEvent产生后是怎样在View之间传递及处理的. 首先介绍一下什么是MotionEvent.所谓MotionEv ...

  8. 浅谈Android中的组播(多播)

    组播使用UDP对一定范围内的地址发送相同的一组Packet,即一次可以向多个接受者发出信息,其与单播的主要区别是地址的形式.IP协议分配了一定范围的地址空间给多播(多播只能使用这个范围内的IP),IP ...

  9. Android中的onActivityResult和setResult方法的使用

    如果你想在Activity中得到新打开Activity关闭后返回的数据,你需要使用系统提供的startActivityForResult(Intent intent,int requestCode)方 ...

随机推荐

  1. Linux下java进程CPU占用率高-分析方法

    今天登陆同事的一台gateway 开始以为hive环境登陆不了了,仔细一看看了下是因为机器很卡,我每次等几秒没登陆就ctrl+c了,看了下是有个java进程cpu:340.4%  mem:14.6%  ...

  2. 微信浏览器的HTTP_USER_AGENT

    在iPhone下,返回   1 Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, lik ...

  3. Ubuntu搭建Note.Js 平台

    1. 安装nodeJs和npm apt-get install nodejsapt-get install npm 2 .node有一个模块叫n,是专门用来管理node.js的版本的.首先安装n模块: ...

  4. 基本shell编程【2】-服务端发布脚本

    set -x deployBase="/var/lib/tomcat7/webapps" bakBase="/root/bak" echo "auto ...

  5. 【2016-10-25】【坚持学习】【Day12】【WPF】【Telerik】【VirtualtionData 虚拟化数据】

    VirtualQueryableCollectionView When working with the UI components that enable UI Virtualization, yo ...

  6. Fast RCNN 训练自己数据集 (2修改数据读取接口)

    Fast RCNN训练自己的数据集 (2修改读写接口) 转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ http ...

  7. css3属性-webkit-font-smoothing

    对字体进行抗锯齿渲染可以使字体看起来会更清晰舒服.在图标字体成为一种趋势的今天,抗锯齿渲染使用也越来越多. font-smoothing是非标准的CSS定义.它被列入标准规范的草案中,后由于某些原因从 ...

  8. 一切Web的基础----HTTP

    HTTP 是基于 TCP/IP 协议的应用层协议.它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口.HTTP协议基于TCP连接,该协议针对TCP连接上的数据 ...

  9. Maven配置详见

    CSDN 2016博客之星评选结果公布    [系列直播]零基础学习微信小程序!      "我的2016"主题征文活动   博客的神秘功能 maven 配置详解 标签: mave ...

  10. [No00007D]2016-面经[上]

    面试常见问题: 题一:"请你自我介绍一下" 思路:1.这是面试的必考题目.2.介绍内容要与个人简历相一致.3.表述方式上尽量口语化.4.要切中要害,不谈无关.无用的内容.5.条理要 ...