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