Serializable ve Parcelable ile Sayfalar Arası Nesne Taşıma

Genellikle sayfalar arası veri taşınması gerektiğinde bunu Intent yardımıyla yaparız ve Intent ile String,int,float,boolean vs gibi değişkenler taşıyabiliriz.

Ama ya nesne taşımak istersek ve bunu optimize bir şekilde gerçekleştirmek istersek ne yapmalıyız?

Burada karşımıza iki farklı yol çıkıyor.

  1. Serializable
  2. Parcelable

 

Serializable nedir?

Serializable, java ile birlikte gelen standart bir arayüzdür.Basittir ve kullanışlıdır.Sadece bu arayüzü kullanarak oluşturduğumuz nesnemizi (Pojomuzu) sayfalar arasında taşıyabiliriz.Aşağıdaki gibi bir kullanım Serializable örneği olmaktadır.

 

insan.class
 
import java.io.Serializable;
public class insan implements Serializable {
    private String isim;
    private int yas;
    private char cinsiyet;
    public insan(String isim, int yas, char cinsiyet) {
        this.isim = isim;
        this.yas = yas;
        this.cinsiyet = cinsiyet;
    }
    public String getIsim() {
        return isim;
    }
    public int getYas() {
        return yas;
    }
    public char getCinsiyet() {
        return cinsiyet;
    }
}

 

MainActivity.class
 
        insan süleyman=new insan("Süleyman",22,'E');
        Intent intent=new Intent(this,gecisActivity.class);
        intent.putExtra("insanNesnesi",süleyman);
        startActivity(intent);

 

gecisActivity.class
 
        Intent intent = getIntent();
        insan gelenInsanNesnesi = (insan) intent.getSerializableExtra("insanNesnesi");

 

Serializable ile sayfalar arası nesne taşınması aslında bu kadar basit.Ama görünürde her ne kadar basit gözükse de işin arka kısmında bir sorun var.Arka planda nesneyi yansıtma işlemi yaparken ve diğer sayfaya geçirme işlemini yaparken birden çok nesne oluşturur.Bu yüzden arka planda  çok sayıda çöp hale gelen ve hafızada yer kaplayan nesneler oluşur.Sonuç olarak performans kaybına neden olmaktadır.

Bu durumu gören Google, android için ayrı bir arayüz olan Parcelable’yi geliştirdi.

 

Parcelable nedir?

 

Parcelable’da Seralizable gibi bir arayüzdür ama android için özel tasarlanmış bir arayüzdür.Arka planda yansıtma işlemi yapmaz ve bunun sayesinde performansta düşüş sağlamaz.

Aşağıdaki parcelable örneğini inceleyelim.

insan.class
 
import android.os.Parcel;
import android.os.Parcelable;
public class insan implements Parcelable {
    private String isim;
    private int yas;
    private char cinsiyet;
    public insan(String isim, int yas, char cinsiyet) {
        this.isim = isim;
        this.yas = yas;
        this.cinsiyet = cinsiyet;
    }
    public String getIsim() {
        return isim;
    }
    public int getYas() {
        return yas;
    }
    public char getCinsiyet() {
        return cinsiyet;
    }
    protected insan(Parcel in) {
        isim = in.readString();
        yas = in.readInt();
        cinsiyet = (char) in.readInt();
    }
    public static final Creator<insan> CREATOR = new Creator<insan>() {
        @Override
        public insan createFromParcel(Parcel in) {
            return new insan(in);
        }
        @Override
        public insan[] newArray(int size) {
            return new insan[size];
        }
    };
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(isim);
        dest.writeInt(yas);
        dest.writeInt((int) cinsiyet);
    }
}

 

MainActivity.class
 
       insan süleyman=new insan("süleyman",22,'E');
        Intent intent=new Intent(this,gecisActivity.class);
        
        intent.putExtra("insanNesnesi",süleyman);
        startActivity(intent);

 

gecisActivity.class
 
        Intent intent=getIntent();
        insan gelenNesne=intent.getParcelableExtra("insanNesnesi");

Parcelable kullanıldığında nesne sınıfına daha fazla kod ekleniyor ama bunun performans farkı bulunmakta.Geri kalan kodlarsa neredeyse aynı olmakta.

 

 

Serializable vs Parcelable

 

Yapmış olduğum araştırmalarda bu iki arayüzün karşılaştırma sonuçlarını tam olarak doğru cevaplarını bulamadım.

Philippe Breault isimli bir abimiz bunun için bir test yapmış ve testte şunları uygulamış :

  • Nesneyi bundle paketine koymuş ve aktiviteler arası geçirme işlemi uygulamış.
  • Bu geçirme işlemini döngüye eklemiş ve 1000 defa gerçekleşmesini işlemiş.
  • Testi hem Serializable hem de Parcelable ile gerçekleştirmiş ve aşağıdaki grafiği elde etmiş.

Nexus 10
Serializable: 1.0004ms,  Parcelable: 0.0850ms – 10.16x performans
Nexus 4

Serializable: 1.8539ms – Parcelable: 0.1824ms – 11.80x performans

Desire Z

Serializable: 5.1224ms – Parcelable: 0.2938ms – 17.36x performans

 

Phil abimizin yaptığı testler sonucunda sayfalar arası veri aktarımında Parcelable kullanmanın Serializable kullanımına göre 10 kat daha performanslı çalıştığını ortaya koymuş ve bize de Parcelable kullanmamızı tavsiye etmiş.

 

 

Başka bir testteyse Alexey Frishman adlı abimiz örnek bir proje yapmış.

  • Bir adet 5 seviyeli nesne ağacı oluşturmuş.
  • İlk 4 seviyedeki her bir ağaç düğümünün de 10 alt düğümü olacak şekilde yapmış.
  • Son seviye düğümleride yapraklarla doldurmuş.
  • Toplamda ağaçtaki nesne sayısını 1 + 10 + 100 + 1000 + 10000 = 11111 olarak bulmuş.
  • Ağacı Serializable ve Parcelable olarak ayrı ayrı aktarma işlemleri yapmış.
  • Son olarak LG Nexus cihazında bunu 10 defa gerçekleştirmiş ve aşağıdaki sonuçları bulmuş.

Alexey Abimizin Test sonuçları

Parcel: ort. 250 ms

Unparcel: ort. 232 ms

Serialize: ort. 70 ms

Deserialize: ort. 141 ms

 

Yani yukarıda görüldüğü gibi tam olarak kesin bir cevabını bulamıyor.Ama bence Android için Serializable yeterli gelseydi Google Mühendisleri Parcelable’yi çıkartıp bizlere bunu kullanmamızı önermezdi.

Her ne olursa olsun ikisi arasındaki fark milisaniyenin yüzlerce biri gecikme süresinde olacaktır.

Yeterki stabil,performanslı ve güzel bir uygulamamız olsun.

 

Kaynakça :