activity間傳遞值
通過Intent啟動另一個activity
傳遞簡單資料(八大基本資料型別+String)
傳遞簡單資料的代碼片段
Intent intent = new Intent(MainActivity.this, AdditionalActivity.class);
intent.putExtra("INT",12);
intent.putExtra("CHAR",'字');
intent.putExtra("str","張勝利");
intent.putExtra("BOOLEAN",true);
······
接收簡單資料的代碼片段
Intent intent = getIntent();
// 不需要設定默認值
String str = intent.getStringExtra("str");
//需要設定默認值
int INT = intent.getIntExtra("INT",0);
char CHAR = intent.getCharExtra("CHAR",' ');
boolean BOOLEAN = intent.getBooleanExtra("BOOLEAN",false);
······
傳遞資料包Bundle
傳遞資料包Bundle的代碼片段
Intent intent = new Intent(MainActivity.this, AdditionalActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name","李師師");
bundle.putInt("age",18);
ArrayList<String> list = new ArrayList<>();
for (int i = 1; i < 10; i++) {
list.add("王文武"+i);
}
bundle.putStringArrayList("list",list);
······
intent.putExtras(bundle);
startActivity(intent);
接收資料包Bundle的代碼片段
Intent intent = getIntent();
// 獲取資料包Bundle
Bundle data = https://www.cnblogs.com/qisha/archive/2021/11/12/intent.getExtras();
int age = data.getInt("age");
String name = data.getString("name");
ArrayList<String> list = data.getStringArrayList("list");
······
傳遞值物件
值物件傳遞時需要對物體類物件進行序列化,可使用java.io中的Serializable;或者使用android.os中的Parcelable,實作自定義序列化
通過JDK自帶的序列化介面Serializable實作的物件類
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 User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
通過實作Parcelable介面自定義序列化物件類
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public User() {
}
protected User(Parcel in) {
name = in.readString();
age = in.readInt();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
// 寫資料進行保存
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
//用來創建自定義的Parcelable的物件
public static final Creator<User> CREATOR = new Creator<User>() {
//創建自定義的Parcelable的物件
@Override
public User createFromParcel(Parcel in) {
return new User(in.readString(),in.readInt());
}
//讀取資料進行恢復
@Override
public User[] newArray(int size) {
return new User[size];
}
};
}
傳遞值物件的代碼片段
傳遞值物件的時候可以直接使用Intent類中的putExtra()方法
Intent intent = new Intent(MainActivity.this, AdditionalActivity.class);
intent.putExtra(new User("趙柳",23));
startActivity(intent);
接收值物件的代碼片段
接收值物件時需要區分值物件是通過那種方式實作的序列化介面
- 通過Serializable介面實作序列化
可以使用Intent類中的getSerializableExtra()方法獲取物件,但需要強轉成對應的物體類物件, - 通過Parcelable介面實作序列化
可以使用Intent類中的getParcelableExtra方法獲取物件,不需要強轉獲取的物件,
Intent intent = getIntent();
//通過Serializable介面實作的序列化的物件類
//User user1= (User) intent.getSerializableExtra("user1");
//通過Parcelable介面實作的自定義序列化的物件類
User2 user2 = intent.getParcelableExtra("user2");
······
Serializable 和Parcelable 的區別
作用
Serializable的作用是為了保存物件的屬性到本地檔案、資料庫、網路流、RMI(Remote Method Invocation)以方便資料傳輸,當然這種傳輸可以是程式內的也可以是兩個程式間的,使用了反射技術,并且期間產生臨時物件
Android的Parcelable的設計初衷是因為Serializable效率過慢,為了在程式內不同組件間以及不同Android程式間(AIDL)高效的傳輸資料而設計,這些資料僅在記憶體中存在,Parcelable是通過IBinder通信的訊息的載體,
效率及選擇
Parcelable的性能比Serializable好,在記憶體開銷方面較小,所以在記憶體間資料傳輸時推薦使用Parcelable,如activity間傳輸資料,而Serializable可將資料持久化方便保存,所以在需要保存或網路傳輸資料時選擇Serializable,因為android不同版本Parcelable可能不同,所以不推薦使用Parcelable進行資料持久化
高級功能上
Serializable序列化不保存靜態變數,可以使用transient關鍵字對部分欄位不進行序列化,也可以覆寫writeObject、readObject方法以實作序列化程序自定義
如果用transient宣告一個實體變數,當物件存盤時,它的值不需要維持,換句話說,用transient關鍵字標記的成員變數不參與序列化程序,
效率及選擇
對于Serializable,類只需要實作Serializable介面,并提供一個序列化版本id(serialVersionUID)即可,
而Parcelable則需要實作writeToParcel、describeContents函式以及靜態的CREATOR變數(AS有相關插件 一鍵生成所需方法),實際上就是將如何打包和解包的作業自己來定義,而序列化的這些操作完全由底層實作,
代碼實作
從上面我們可以看出Parcel的寫入和讀出順序是一致的,如果元素是list讀出時需要先new一個ArrayList傳入,否則會報空指標例外,如下:
list = new ArrayList<String>();
in.readStringList(list);
PS: 在自己使用時,read資料時誤將前面int資料當作long讀出,結果后面的順序錯亂,報例外,當類欄位較多時務必保持寫入和讀取的型別及順序一致,
本人正在學習中轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/356705.html
標籤:其他
