Activity数据传递详解

0.179字数 1018阅读 102
唉,好久都没有写过博客了。真的是太懒了。最近在看《Android权威编程指南》,挺不错的一本书,感觉里面有很多开发规范,是很值得一看的一本书。
  • 感觉在工作中经常处理Activity之间的数据传递,通常我们都是只用(以前我是的)startActivity(),但是看一些别人的代码中经常用到startActivityForResult()。当时就是感觉很高大上的样子,然后一直不太清楚里面的具体到底是干什么的。但是我看了上面的一本书之后就比较明白了。so,我就想写一篇博客把他们之间的关系写清楚,当然也为下一篇博客打一下基础。
  • 先说一下应用场景吧,有时候我们会从Activity1跳转到Activity2之后,还需要从Activity2中拿到一些处理后的数据那怎么办呢?
  • 通常,以前的我肯定会想,这不是很简单吗?再从Activity2直接调用startActivity跳转到Activity1不就行了嘛,我以前也是这样做的(┬_┬),当然这个方法是可以解决这样的问题的,但是现在我就是觉得这样的方法很low,所以startActivityForResult(),setResult(),onActivityResult()这三个方法就很好解决上面的问题。
  • 下面说一下用法:首先在Activity1中调用startActivityForResult()方法,其实这个是比startActivity()更为高级。现在先看一下Activity的跳转的代码,startActivityForResult()会比startActivity多一个参数,第二个参数叫做请求代码,请求代码是先发送给子Activity,然后再返回给父Activity的的整数值。如果在Activity1中只跳转一个Activity的话,是没有用的,但是跳转多个Activity的时候就可以区分不同类型的Activity。
Intent intent=SetActivity.newIntent(StartActivity.this,true);
startActivityForResult(intent,REQUEST_CODE_CHAT);
  • 当从Activity1跳转到Activity2的时候,需要调用setResult()方法,需要传入两个参数,第一个返回码的值int类型的,第二个参数是Intent类型。一般来说第一个参数可以是一下任意的一个预定义常量:Activity.REUSLT_OK 或者 Activity.RESULT_CANCELED。当然这两个有什么区别呢,当然是有区别的。我们从REUSLT后面就可以猜到,如果没有调用setResult()方法的情况下,用户按了后退按钮,Activity1则会收到收到 Activity.RESULT_CANCELED的结果代码。一般情况下都是填Activity.REUSLT_OK这个code值。
 Intent data=new Intent();
 data.putExtra(EXTRA_SHOW,isAnswerShown);
 //这里可以设置也可以不用设置。要看具体的返回值
 setResult(RESULT_OK,data);
  • 当从Activity2返回到Activity1的时候。需要在Activity1中添加 onActivityResult()回调方法。onActivityResult()中有三个参数,第一个参数requestCode叫做请求值,就是从Activity1中跳转到Activity2中在startActivityForResult()中设置的第二个参数的值。第二个参数resultCode叫做结果值,就是从Activity2中跳转到Activity1中在setResult()中设置的第一个参数的值。最后一个参数data,就是跳转过来传递的值喽。(感觉是不是有点晕)
 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode != Activity.RESULT_OK){
            return;
        }
        //如果只有一个Activity跳转的话,这个判断可以不用写
        if(REQUEST_CODE_CHAT == requestCode){
        if(data==null) return;
            isTure=SetActivity.wasAnswerShown(data);
            Toast.makeText(this,"回来的结果"+isTure,Toast.LENGTH_SHORT).show();
        }

    }
  • 首先判断一下:resultCode 的值是否和在Activity2中setResult()的值是否一样。如果不一样的就returned。如果有多个Activity跳转的话,这里就可以用requestCode用来区分是从那个Activity跳转过来的。最后就可以从data中取值了。下面贴一下俩个Activity的全部代码

第一个Activity,就是我说的Activity1

package zhan.com.typeview.simaple.intent;

import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import zhan.com.typeview.R;

/**
 * @date 创建时间: 2017/11/12 0012 16:25
 * @author zh_legend
 * @Description 跳过去的Activity
 * @Email code_legend@163.com
 * @Version 1.0
 */
public class StartActivity extends AppCompatActivity {

    //响应码
    private  static  final int REQUEST_CODE_CHAT=0;
    //得到的返回值
    private boolean isTure;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);
    }
    public void jump(View v){
        Intent intent=SetActivity.newIntent(StartActivity.this,true);
        startActivityForResult(intent,REQUEST_CODE_CHAT);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode != Activity.RESULT_OK){
            return;
        }
        //如果只有一个Activity跳转的话,这个判断可以不用写
        if(REQUEST_CODE_CHAT == requestCode){
            if(data==null) return;
            isTure=SetActivity.wasAnswerShown(data);
            Toast.makeText(this,"回来的结果"+isTure,Toast.LENGTH_SHORT).show();
        }

    }
}

第二个Activity,就是我说的Activity2

package zhan.com.typeview.simaple.intent;

import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import zhan.com.typeview.R;

import static android.icu.lang.UCharacter.GraphemeClusterBreak.T;
/**
 * @date 创建时间: 2017/11/12 0012 16:24
 * @author zh_legend
 * @Description  返回过去的
 * @Email code_legend@163.com
 * @Version 1.0
 */
public class SetActivity extends AppCompatActivity {

    //返回的结果
    private static final String EXTRA_IS_TRUE="zhan.com.typeview.simaple.intent.is_true";

    private static final String EXTRA_SHOW="zhan.com.typeview.simaple.intent.show";

    //跳转得到的结果
    private boolean isAnsTrue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_set);
        Intent intent = getIntent();
        isAnsTrue=intent.getBooleanExtra(EXTRA_IS_TRUE,false);
        Toast.makeText(this,"跳转过来的结果"+isAnsTrue,Toast.LENGTH_SHORT).show();
        setAnswerShowResult(false);
    }

    public static Intent newIntent(Context packageContext,boolean answerIsTrue){
        Intent intent=new Intent(packageContext,SetActivity.class);
        intent.putExtra(EXTRA_IS_TRUE,answerIsTrue);
        return intent;
    }

    public static boolean wasAnswerShown(Intent result){
        return result.getBooleanExtra(EXTRA_SHOW,false);
    }

    private void setAnswerShowResult(boolean isAnswerShown){
        Intent data=new Intent();
        data.putExtra(EXTRA_SHOW,isAnswerShown);
        //这里可以设置也可以不用设置。要看具体的返回值
        setResult(RESULT_OK,data);
    }


}

  • 最后总结一下,感觉里面的代码有很多借鉴支持,首先是Activity之间跳转,我们一般都是写到第一个Activity中的,但是作者的写法却写到了需要跳转的Activity里面,感觉这种思想真的挺不错。最直观的好处就是数据传递的时候参数不容易出错。

好了,就这样吧。

推荐阅读更多精彩内容