Android serialization of those things (Serializable & Parcelable)

I would like to use the article to record the learning process. If there is any error, please indicate it, and please indicate the source when reprinting or citing.

What is serialization? Why? How to do it?

Wikipedia defines serialization as follows:

Serialization is the process of converting the state information of an object into a form that can be stored or transmitted. During serialization, objects write their current state to temporary or persistent storage. Later, the object can be recreated by reading or deserializing the state of the object from the store.

Also, a technique is mentioned:

Binary serialization preserves type fidelity, which is useful for preserving the state of an object between invocations of an application. For example, objects can be shared between different applications by serializing them to the clipboard. You can serialize objects to streams, disk, memory, network, and more. Remoting uses serialization to pass objects between computer application domains "by value".

In a nutshell, serialization is converting an object to binary and then storing it locally/streaming or passing the object over the network to other endpoints.

The above is an introduction to the concept of serialization . You may see it here and think: "Oh, I know the concept of serialization, but why do I need to serialize? Can't data be transmitted without serialization?".

Here's a simple example to explain why serialization is needed:
The simplest way to pass data between activities in Android is nothing more than passing data through intent.putExtra(), such as strings, numbers, and Bundles, etc., but we will find , we cannot pass a Java class object directly through this method .
why?
Because Android copies intent when dealing with Intent, if it is not serialized, it just passes the reference of the object, but obviously if this reference is not static, then nothing can be obtained in the new activity. Therefore, we need to serialize the object and store it in the intent before passing it.

Reference https://stackoverflow.com/questions/14917029/pass-object-reference-within-intent-without-implementing-serializable-or-parcela

After knowing why serialization is needed, let's take a look at the
two :

  • Method 1: Serializable (provided by Java), the class to be passed implements the Serializable interface
  • Method 2: Parcelable (Android exclusive), the class to be passed implements the Parcelable interface

Below we describe these two serialization methods in detail.

Serializable interface, easy to use

  • Serializable is a serialization interface (an empty interface) provided by Java, which is used to identify that the current class can be serialized by ObjectOutputStream and deserialized by ObjectInputStream.

  • Google engineers call this a "marker interface," which means that there is no need to implement a method, as long as the class to be serialized implements the interface, Java will serialize it.

The following example explains how to use Serializable serialization to transfer objects

First, create an entity class Book and implement the Serializable interface

public class Book implements Serializable {

    private static final long serialVersionUID = 123698745L;
    private String name;
    private int price;

    public Book(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

You can see that the implementation of Serializable is very simple, you only need to create an additional serialVersionUID attribute and it will be OK

serialVersionUID is something like a version number, a unique identifier for a serializable class. That is to say, when the class is serialized, it will save its version number. When deserializing, check whether the version number of the object to be deserialized is consistent, and an error will be reported if it is inconsistent.
If we don't create this attribute manually, then when we serialize a class, a slight modification to the class will change the version number. At this point, if we deserialize again, an error will occur.

Pass between activities

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.start_serial).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                Book book = new Book("Android 开发艺术探索",50);
                intent.putExtra("key1",book);
                startActivity(intent);
            }
        });
    }
}

SecondActivity.java

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        TextView textView = findViewById(R.id.my_serial_data);
        Book book = (Book) getIntent().getSerializableExtra("key1");
        textView.setText(String.format("Name is: %s, Price is:%d",book.getName(),book.getPrice()));
    }
}

demo
Serializable is here

Parcelable interface, speed first

  • Parcelable is an Android-specific serialization interface
  • Principle: Decompose a complete object, and each part after decomposition is the data type supported by Intent, so as to realize the function of passing the object

The following is an example to explain how to use Parcelable serialization to pass objects

First, create an entity class that implements the Parcelable interface
People.java

public class People implements Parcelable {

    //成员属性和set() & get() 方法
    private String name;
    private String sex;
    private int age;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    //默认构造函数
    public People() {
    }

    //***************分割线******************
    //以下为实现Parcelable接口后需要实现的方法

    //我们手动创建的构造函数
    protected People(Parcel in) {
        readFromParcel(in);
    }

    //用于实现序列化
    //将对象转换成一个Parcel对象
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(sex);
        dest.writeInt(age);
    }

    //用于反序列化
    public static final Creator<People> CREATOR = new Creator<People>() {
        //反序列化创建对象
        @Override
        public People createFromParcel(Parcel in) {
            return new People(in);
        }

        //反序列化创建对象数组
        @Override
        public People[] newArray(int size) {
            return new People[size];
        }
    };

    //内容描述
    @Override
    public int describeContents() {
        //除了当前对象中存在文件描述符时返回1,其余都返回0
        return 0;
    }

    //通过反序列化得到的 Parcel 构造对象,注意需要与序列化过程写入的顺序一致
    private void readFromParcel(Parcel in){
        name = in.readString();
        sex = in.readString();
        age = in.readInt();
    }
}

Above, in addition to the basic member properties and get() & set() methods, we can automatically add methods through Alt+Enter. So in fact we don't need to do too much work, most of AS has already done it for us.

Pass between activities

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ....
        findViewById(R.id.start_parcel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,ThreeActivity.class);
                People people = new People();
                people.setName("whdalive");
                people.setSex("man");
                people.setAge(21);
                intent.putExtra("key2",people);
                startActivity(intent);
            }
        });
    }
}

ThreeActivity.java

public class ThreeActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_three);
        TextView textView = findViewById(R.id.my_parcel_data);
        People people = (People) getIntent().getParcelableExtra("key2");
        textView.setText(String.format("Name is : %s, Sex is : %s, Age is: %d",people.getName(),people.getSex(),people.getAge()));
    }
}

demo

Parcelable probably has so much.

Serializable Vs. Parcelable

  • effectiveness

  • coding

    • Serializable is simpler, just implement the interface
    • Parcelable is slightly complicated and needs to override several key methods
  • Implementation principle
    • Serializable: Implemented through reflection mechanism, serialization is slow; this mechanism will create many temporary objects during serialization, which is easy to trigger garbage collection (GC).
    • Parcelable: Decompose complete objects into data types supported by Intent (real serialization instead of reflection), so it is very efficient
  • Application scenarios

    • Serializable: Local Persistent Storage & Network Transmission
    • Parcelable: IPC (inter-process communication); not suitable for permanent storage: because Parcelable cannot guarantee the continuity of data when there are changes in the outside world

      As for why? Way Google's original text:

      Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.


Finally put the Demo address above

DemoParcelableSerializable


Summarize

  • This article summarizes the two ways of serialization in Android
  • The author's level is limited, if there are any mistakes or omissions, please correct me.
  • Next, I will also share the knowledge I have learned. If you are interested, you can continue to pay attention to the Android development notes of whd_Alive.
  • I will share technical dry goods related to Android development from time to time, and look forward to communicating and encouraging with you.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326041046&siteId=291194637