1. 程式人生 > >【Android筆記】用Intent在多個Activity之間傳遞引數

【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鍵之後把資料返回。這個大家可以自己試試