Android中數據的傳遞以及對象序列化


Android中當兩個Activity需要有信息交互的時候,可以使用Intent。具體來說:

發送單一類型數據:

發送方:
String data = "Hello SecondActivity";
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("extra_data", data);
startActivity(intent); #在onClick中調用
接收方:
Intent  intent = getIntent();
String data = intent.getStringExtra("extra_data");#可以在onCreate中讀取

除了putExtra("key", value)/getStringExtra("key")之外, 根據傳遞的value的類型還有很多對,比如:

putExtra("key", intvalue)/getintExtra("key")
putExtra("key", floatvalue)/getfloatExtra("key")
putExtra("key", doublevalue)/getDoubleExtra("key")
putExtra("key", bundlevalue)/getBundleExtra("key")

...

發送多種數據類型的組合:

也可以用Bundle把很多數據類型(包括嵌套Bundle)放到Bundle中一並發送:

//sender
Bundle b = new Bundle(); b.putInt("age", 2); b.putString("data", "hello"); intent.putExtras(b); startActivity(intent);
//receiver
Intent i = getIntent(); Bundle b = i.getExtras(); int age = b.getInt("age"); String data = b.getString("data");

發送類對象:

只有實現了Serializable或者Parcelable接口的類對象才可以實現序列化並可以通過Intent和Binder傳遞。

方法1:Serializable

Serializable是Java提供的序列化方法,優點是使用簡單,一切由系統負責;缺點是速度稍慢。

public class User implements Serializable{
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public User(String name, Integer age){
        this.name = name;
        this.age = age;
    }
}
//sender
intent.putExtra("user", (Serializable) new User("JM", 30));

//Receiver Intent i = getIntent(); User user = (User) i.getSerializableExtra("user"); textView.setText(String.format("name: %s, age: %s", user.getName(), user.getAge()));

注:聲明一個類為Serilizable時,可以一起指定serialVersionUID變量,類型為private static final long。

這個變量的主要作用是保證類可以被正常序列化,比如當前類和序列化的類發生了某些變化,比如成員變量的數量,類型可能發生了改變,這個時候是無法正常反序列化的,會報如下錯誤,程序會Crash:

Main; local class incompatible: stream classdesc serialVersionUID = ********

 

方法2:Parcelable

public class User implements Parcelable{
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public User(String name, Integer age){
        this.name = name;
        this.age = age;
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        //write all the fields that want to send
        parcel.writeString(getName());
        parcel.writeInt(getAge());
    }

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

        @Override
        public User[] newArray(int i) {
            return new User[i];
        }
    };
}
//Sender
            intent.putExtra("user", (Parcelable) new User("JM", 30));
                startActivity(intent);
//Receiver
        User user = (User) i.getParcelableExtra("user");
        textView.setText(String.format("name: %s, age: %s", user.getName(), user.getAge()));

如果在User中有多個同類型字段,比如String,可以用Bundle來實現:

@Override
    public void writeToParcel(Parcel parcel, int i) {
        //write all the fields that want to send
//        parcel.writeString(getName());
//        parcel.writeInt(getAge());
        Bundle b = new Bundle();
        b.putString("name", getName());
        b.putInt("age", getAge());
        parcel.writeBundle(b);
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel parcel) {
//            return new User(parcel.readString(), parcel.readInt());
            Bundle b = parcel.readBundle();
            return new User(b.getString("name"), b.getInt("age"));
        }

        @Override
        public User[] newArray(int i) {
            return new User[i];
        }
    };


系統中很多類是實現了Parcelble接口的類,他們都是可以直接序列化的,比如Intent、Bundle、Bitmpa的呢個,同時List和Map也可以序列化,前提是他們里面的每個元素都是可序列化的。

Serializable是Java中的序列化接口,使用起來簡單但是開銷大,序列化和反序列化需要大量的I/O操作。而Parcelable是Android的序列化方式,因此更適合Android平台,缺點是使用稍微麻煩,但是效率高。

Parcelable主要用於內存序列化。Serialzable主要用於序列化到存儲設備或者序列化后通過網絡傳輸。

 

從別的Activity得到返回結果:

啟動端:

startActivityForResult(intent, 0);

0表示請求碼,說明此次請求的意圖是什么。

接收端:

        Intent i = new Intent();
        i.putExtra("data", editText.getText().toString());
        setResult(RESULT_OK, i);
        finish();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM