【Android笔记】用Intent在多个Activity之间传递参数

 

一、向下一个活动传递数据

前面我们在介绍Intent的时候有说过,我们可以利用Intent在不同组件之间传递数据,接下来这篇文章就是记录如何利用Intent在不同Activity之间传递简单数据、传递数据包、传递值对象以及返回数据给上一个活动的知识。

1. 传递简单数据

主要方法:
putExtra(String name,String value);
putExtra(String name,int value);
(putExtra()有多种重载方法,这里不一一列举)
第一个参数是是键(即要传递数据的名字);
第二个参数是要传递的数据(可以使String型、int型、double型等等)。
getIntent();
getStringExtra(String name);
getInExtra(String name);
参数是前面的键,也即是要传递数据的名字。

思路
①用Intent提供的一系列putExtra()方法(各种重载方法)将要传递的数据暂存在Intent中。
在MainActivity中,

        case R.id.button1:
             intent = new Intent(MainActivity.this,Aty1.class);
             intent.putExtra("data_aty1","这是从MainActivity传入Aty1的数据:"+data);
             startActivity(intent);
             break;

②在下一个活动中用Intent提供的getStringExtra()方法将传递的数据取出。
在Aty1的onCreate()方法中:

        tv_aty1 = (TextView)findViewById(R.id.textView_aty1);
        Intent intent = getIntent();
        String tempData = intent.getStringExtra("data_aty1");
        tv_aty1.setText(tempData);

效果图:
 

2. 传递数据包

主要方法:
Bundle();方法中存储数据包的方法:
putString(String name,String value); //存储字符串在Bundle包中
putInt(String name,int value); //存储整型数据在Bundle包中
等(还可以有float型,double型等,就不一一列出来了)
putExtras(Bundle extras);
参数extras为数据包Bundle的实例

putExtra(String name,Bundle value);
name是数据包的名字,方便传递进其他活动中取出;
value为数据包Bundle的实例。
③getIntent();
④Intent中提供有:
getExtras();方法
getBundleExtra(String name);方法
name是②种数据包的名字。
⑤取出数据包中的具体属性:
getString(String name);
getInt(String name);等等

思路:
①将一系列的数据(包括字符串、整型、布尔型等等)整合在Bundle包中(利用putString()、putInt()等方法),用Intent中的putExtras()或者putExtra()方法传递给其他活动。
在MainActivity中,

           case R.id.button2:
                intent = new Intent(MainActivity.this,Aty2.class);
                Bundle bundle = new Bundle();
                bundle.putString("name",data);
                bundle.putInt("age",18);
                intent.putExtras(bundle);
                startActivity(intent);
                break;

②在下一个活动中,利用getExtras()或getBundleExtra()方法将Bundle包传递过来,然后利用Bundle中的getString()等方法将数据取出来。
在Aty2的onCreate()方法中:

        Intent intent = getIntent();
        Bundle bundle = intent.getExtras();
        et_aty2.setText(String.format("姓名:%s     年龄:%d",bundle.getString("name"),bundle.getInt("age") ));

效果图:
 

假如sex在Bundle包中不存在,可以写成

        et_aty2.setText(String.format("姓名:%s     年龄:%d    性别:%s",bundle.getString("name"),bundle.getInt("age"),bundle.getString("sex","女") ));

效果图:
这里写图片描述

假如sex在Bundle包中存在且赋值为”男”,此时获取数据中还是写成bundle.getString("sex","女") ));,会发生什么呢?可以动手试试。

3. 传递值对象

值对象:自定义的,有数据类型的对象。
有两种序列化对象的接口可以用于传递值对象:
java.io.Serializable
android.os.Parcelable
接下来分别介绍一下这两种接口是如何传递值对象的。

(1) Serializable序列化接口

这是java语言内置的用于序列化对象的接口,只需要implements Serializable,其余的系统会自动处理,因此效率会比较低。
①新建一个java类——User.java(implrments Serialiable)

import java.io.Serializable;

public class User implements Serializable{

    private String name;
    private int age;

    //两个参数的构造方法
    public User(String name,int age){
        this.name = name;
        this.age = age;
    }

    public String getName(){
        return name;
    }

    public int getInt(){
        return age;
    }
}

②用putExtra()方法将User中的数据保存在MainActivity中

           case R.id.button3:
                intent = new Intent(MainActivity.this,Aty3.class);
                User user = new User(data,19);
                intent.putExtra("user",user);
                startActivity(intent);
                break;

③在Aty3中用getSerialiableExtra()方法将数据取出

        Intent intent = getIntent();
        User user = (User)intent.getSerializableExtra("user");
        tv_aty3.setText(String.format("名字:%s     年龄:%d",user.getName(),user.getInt()));

效果图:
 

(2) Parcelable序列化接口

这是Android平台提供的用于序列化对象的接口,使用该接口需要重写一系列与数据有关的方法,因此效率较Serialiable接口高。
①新建一个java类——User2.java(implrments Parcelable)

import android.os.Parcel;
import android.os.Parcelable;

public class User2 implements Parcelable {

    private String name;
    private int age;

    //两个参数的构造方法
    public User2(String name,int age){
        this.name = name;
        this.age = age;
    }

    public String getName(){
        return name;
    }

    public int getAge(){
        return age;
    }
}

②如果只是这样写的话,系统会报错
这里写图片描述
③因此我们要重写一些方法,此时系统会给出提示:
这里写图片描述
因此我们要重写describeContents()方法和writeToParcel()方法
a).describeContents()这个方法只需要重写,暂时不用管。

@Override
    public int describeContents() {
        return 0;
    }

b).writeToParcel()我们要在这个方法里向目标Parcel写数据,因为Parcelable接口没有全自动地序列化机制,它需要我们手动写。

@Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(getName());
        parcel.writeInt(getAge());
    }

④除此之外,我们还需要重写如下方法去读取数据。

public static final Creator<User2> CREATOR = new Creator<User2>() {
        @Override
        public User2 createFromParcel(Parcel in) {
            return new User2(in.readString(),in.readInt());
        }

        @Override
        public User2[] newArray(int size) {
            return new User2[size];
        }
    };

⑤最后我们在Aty4里调用getParcelableExtra()方法接收数据。

Intent intent = getIntent();
        User2 user2 = intent.getParcelableExtra("user2");
        tv_aty4.setText(String.format("姓名:%s     年龄:%d ",user2.getName(),user2.getAge()));

效果图:
 

注:这两种接口方式我也没有理解的很深奥,只是将自己的理解记录下来,如果有错误的话,可以小小地喷一下,最重要的是希望能指出我理解的不正确的地方。

二、返回数据给上一个活动

前面我们讲了向下一个活动传递数据,接下来我们就讲讲把数据返回给上一个活动。
相关方法:
startActivityForResult(Intent intent,int requestCode);
该方法跟startActivity()方法一样,也是用于启动活动的,但这个方法期望在活动销毁的时候能够返回一个结果给上一个活动。
参数1还是Intent;
参数2是请求码,用于在之后的回调中判断数据的来源。
setResult(int resultCode,Intent data);
这个方法是专门用于向上一个活动返回数据的。
参数1用于向上一个活动返回处理结果,一般只使用RESULT_OK或RESULT_CANCELED这两个值;
参数2则把带有数据的Intent传递回去。

①在MainActivity中,调用startActivityForResult()方法启动Aty5。

                case R.id.button5:
                intent = new Intent(MainActivity.this,Aty5.class);
                startActivityForResult(intent,1);
                break;

②在Aty5中注册一个按钮,在点击事件中添加返回数据的逻辑并返回主页面。

                Intent intent = new Intent();
                String data = et_aty5.getText().toString();
                intent.putExtra("data_aty5",data);
                setResult(RESULT_OK,intent);
                finish();

③由于我们是使用startActivityForResult()方法来启动Aty5的,在Aty5被销毁之后会回调上一个活动的onActivityResult()方法,因此我们需要在MainActivity中重写这个方法来得到返回数据。

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case 1:
                if(resultCode == RESULT_OK){
                    String str = data.getStringExtra("data_aty5");
                    tv_atymain.setText(str);
                }
                break;
            default:
                break;
        }
    }

效果图:
 

我们还可以通过在Aty5中重写onBackPressed()方法,使按下Back键之后把数据返回。这个大家可以自己试试

猜你喜欢

转载自blog.csdn.net/az44yao/article/details/112638273