Android关于startActivityForResult的一切

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方法之后调用,会没有结果,无法将结果返回。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值