startActivityForResult用法详解

本文详细介绍了Android中如何在不同Activity之间传递数据,包括使用startActivityForResult和onActivityResult方法的具体步骤,以及requestCode和resultCode的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、如果想在Activity中得到新打开Activity 关闭后返回的数据,需要使用系统提供的startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新的Activity 关闭后会向前面的Activity传回数据,为了得到传回的数据,必须在前面的Activity中重写onActivityResult(int requestCode, int resultCode, Intent data)方法。

复制代码
package com.ljq.activitys; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private final static String TAG="MainActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btnOpen=(Button)this.findViewById(R.id.btnOpen); btnOpen.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { //得到新打开Activity关闭后返回的数据 //第二个参数为请求码,可以根据业务需求自己编号 startActivityForResult(new Intent(MainActivity.this, OtherActivity.class), 1); } }); } /** * 为了得到传回的数据,必须在前面的Activity中(指MainActivity类)重写onActivityResult方法 * * requestCode 请求码,即调用startActivityForResult()传递过去的值 * resultCode 结果码,结果码用于标识返回数据来自哪个新Activity */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { String result = data.getExtras().getString("result");//得到新Activity 关闭后返回的数据 Log.i(TAG, result); } }
复制代码

当新Activity关闭后,新Activity返回的数据通过Intent进行传递,android平台会调用前面Activity 的onActivityResult()方法,把存放了返回数据的Intent作为第三个输入参数传入,在onActivityResult()方法中使用第三个输入参数可以取出新Activity返回的数据。

                    

二、使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新Activity关闭前需要向前面的Activity返回数据需要使用系统提供的setResult(int resultCode, Intent data)方法实现:

复制代码
package com.ljq.activitys; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class OtherActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.other); Button btnClose=(Button)findViewById(R.id.btnClose); btnClose.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { //数据是使用Intent返回 Intent intent = new Intent(); //把返回数据存入Intent intent.putExtra("result", "My name is linjiqin"); //设置返回数据 OtherActivity.this.setResult(RESULT_OK, intent); //关闭Activity OtherActivity.this.finish(); } }); } }
复制代码

setResult()方法的第一个参数值可以根据业务需要自己定义,上面代码中使用到的RESULT_OK是系统Activity类定义的一个常量,值为-1,代码片断如下:
public class android.app.Activity extends ......{
  public static final int RESULT_CANCELED = 0;
  public static final int RESULT_OK = -1;
  public static final int RESULT_FIRST_USER = 1;
}

运行结果

      

说明:当点击“打开新的Activity”按钮,会跳转到“我是新打开的Activity”页面;

        当点击“关闭”按钮,关闭当前页面,同时跳转到“我是旧的Activity”页面,且会传递result参数给前一个Activity

                         

   

请求码的作用                

使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这两个按钮都会打开同一个Activity,不管是那个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由哪个按钮打开的,并且要做出相应的业务处理,这时可以这样做:
 @Override  public void onCreate(Bundle savedInstanceState) {
        ....
        button1.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 1);

           }

        });
        button2.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                 startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 2);

            }

        });

                          
       @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
               switch(requestCode){
                   case 1:
                   //来自按钮1的请求,作相应业务处理
                   case 2:
                   //来自按钮2的请求,作相应业务处理
                }
          }
}
注意:如果在onActivityResult(int requestCode, int resultCode, Intent data)方法中,依据requestCode进行判断的话,

由于逻辑业务需求,通常会在switch分支语句外面添加if(resultCode == RESULT_OK){}的判断,

因为,返回键或者直接finish()的操作也会进入onActivityResult方法中!            

                    

结果码的作用

在一个Activity中,可能会使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。为了知道返回的数据来自于哪个新Activity,在onActivityResult()方法中可以这样做(ResultActivity和NewActivity为要打开的新Activity):
public class ResultActivity extends Activity {
       .....
       ResultActivity.this.setResult(1, intent);
       ResultActivity.this.finish();
}
public class NewActivity extends Activity {
       ......
        NewActivity.this.setResult(2, intent);
        NewActivity.this.finish();
}
public class MainActivity extends Activity { // 在该Activity会打开ResultActivity和NewActivity
       @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
               switch(resultCode){
                   case 1:
                   // ResultActivity的返回数据
                   case 2:
                    // NewActivity的返回数据
                }
          }

注意事项:

1.Android系统在Activity类中定义了三种返回码:RESULT_OK(-1)、RESULT_CANCELED(0)、RESULT_FIRST_USER(1)

在其他系统中,OK通常使用1表示,而此处Android系统使用0表示OK,通过第三个默认值RESULT_FIRST_USER可以看出,系统

将大于0的数字留给了开发人员自己定义。

同时,requestCode必须大于或等于0,否则startActivityForResult变成了startActivity效果啦,也就是返回时无法进入onActivityResult方法中!

同时,requestCode不能太大,否则start失效,日志报错:

Caused by: java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode!

在启动的Activity中,调用finish()方法和返回键操作时,在之前Activity的onActivityResult方法中,resultCode均为 RESULT_CANCELED。


2.Activity类也提供了有时在复杂的业务逻辑中,可能存在A startActivityForResult 到B,同时C也startActivityForResult 到B,且requestCode

可能相同(以表示同意业务请求),这时可能需要在B中针对性的判断此请求来源(来自于A还是C)。此时,可以通过intent传参形式。

相信大家都比较熟悉,其实Activity类中也提供了相应的函数可以获取到来源Activity的类型函数:getCallingActivity(),返回

ComponentName对象。但需要注意此函数仅针对startActivityForResult有效,返回的结果中包含完整包名。


3.startActivityForResult函数组合A-->B:针对Activity B的启动模式为singleTask或singInstance将会失效。

此时,onActivityResult将在A的onpause之后直接回调,且resultCode为RESULT_CANCELED。


4.调用setResult(int resultCode)方法后,必须调用finish()方法,才能返回至之前Activity!


5.android:launchMode="singleTop" 和 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)配合使用:

If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.

For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.

The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished andrestarted with the new intent. If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be delivered to the current instance's onNewIntent().

注意:如上红色字体标注所示,只有当即将启动的Activity已经存在于task中时,位于当前Activity和即将启动的Activity之间的所有Activity才会销毁!

            如果即将启动的Activity当前不存在于task中,使用intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)也能达到效果,

但是会出现App切换时的闪频现象(从一个task跳转至另一个task之间的过度效果),所以不建议如此使用,可以通过在自定义Application文件中添加一个管理Activity

的ArrayList(BaseActivity的onCreate中add,onDestroy中remove)来达到关闭应用程序或者Finish当前所有Activity的功能!

使用详情如上所述,需要注意的是,二者配合使用时,由于之前Activity并没有re-created,而是restarted,

所以,getIntent()获取的是Activity 创建时传递的那个Intent,此时通过getIntent()无法获取到新Intent传递的数据,

如官方文档所述,之前Activity将会调用onNewIntent(Intent intent)方法,通过参数intent可以获取到传递的数据!










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值