Một Tính Năng Tuyệt Vời Của Kotlin: Parcelize

Bạn sẽ xoá rất nhiều dòng code trong ứng dụng của bạn

Làm thế nào bạn gửi các model (các class bạn định nghĩa của riêng bạn ) giữa các Activity ?

  • Serializable ?
  • EventBus / Otto ?
  • Parcelable ?

Serializable nó không tốt cho hiệu suất trong ứng dụng Android của bạn Libaries Bus giống như EventBus or Ottodễ dàng để sử dụng và có hiệu suất nhưng đôi khi chúng là nguyên nhân gây ra sự quá phức tạp trong code của bạn. Parcelable interfacelà tuyệt vời nhất trong android nhưng chúng lại có quá nhiều boilerplate

Parcelize

Kotlin đã hỗ trợ parcelable trong version 1.1.4. Bây giờ plugin Android Extensions đã thực hiện Parcelable một cách tự động. Việc khai báo các thuộc tính serialized trong primary constructor và thêm anotation @Parcelize và các phương thức writeToParcel()/createFromParcel() sẽ được tạo một cách tự động.

Java model vs Kotlin model

Tôi sẽ tạo 2 ví dụ chính xác của cùng một class với Java và kotlin sử dụng Parcelable Student.java

public class Student implements Parcelable{
        private String id;
        private String name;
        private String grade;

        // Constructor
        public Student(String id, String name, String grade){
            this.id = id;
            this.name = name;
            this.grade = grade;
       }
       // Getter and setter methods
       .........
       .........

       // Parcelling part
       public Student(Parcel in){
           String[] data = new String[3];

           in.readStringArray(data);
           // the order needs to be the same as in writeToParcel() method
           this.id = data[0];
           this.name = data[1];
           this.grade = data[2];
       }

       @Оverride
       public int describeContents(){
           return 0;
       }

       @Override
       public void writeToParcel(Parcel dest, int flags) {
           dest.writeStringArray(new String[] {this.id,
                                               this.name,
                                               this.grade});
       }
       public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
           public Student createFromParcel(Parcel in) {
               return new Student(in); 
           }

           public Student[] newArray(int size) {
               return new Student[size];
           }
       };
   }

Student.kt

@Parcelize
data class Student(val id: String, val name: String, val grade: String) : Parcelable

Yêu cầu bắt buộc

Kotlin version 1.1.4 or mới nhất

Làm sao để sử dụng

Thêm đoạn code bên dưới vào trong file gradle của bạn

androidExtensions {
    experimental = true
}

Ngoài ra bạn cũng cần thêm apply plugin: ‘kotlin-android-extensions’ tới file gradle của bạn. Tuy nhiên nếu bạn đã tạo project hỗ trợ kotlin nó sẽ được thêm vào tự động Sau khi thêm anotation @Parcelize tới model của bạn. Bạn không cần phải viết thêm bất cứ dòng code nào nữa. File model trong kotlin của bạn trong sẽ như bên dưới

package com.digital.kotlinparcelize

import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@Parcelize
data class PersonModel(val name: String, val age: Int) : Parcelable

Một chút về Lint Error

Android Studio sẽ cho 1 Lint errro như bên dưới . Nó report bug tới IntelliJ. Bạn có thể xem những issue liên quan theo link bên dưới https://youtrack.jetbrains.com/issue/KT-19300

Bạn có thể bỏ qua Lint error và chạy project bình thường.

Bên dưới tôi sẽ thực hành cái chúng ta vừa biết bằng cách tạo 2 Activity và gửi data giữa 2 Activity MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val intent = Intent(this, SecondActivity::class.java)
        intent.putExtra("dataModel", PersonModel("Burak", 26))
        startActivity(intent)
    }
}

SecondActivity.kt

class SecondActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        val person = intent.extras.getParcelable<PersonModel>("dataModel")

        toast("Name: ${person.name} age: ${person.age}")
    }
}

All Rights Reserved