Android Parcelable
لإرسال البيانات بين two activities يوجد عدة طرق, كـ shared Preference و database, لكن الطريقة المباشرة للإرسال هي عن طريق Intent بإستخدام الدوال الخاصة بها ()putExtra والتي تتعامل مع جميع الـ Primitive types بطريقة مباشرة, لكن في حال أردنا أن نرسل object أو list of objects سنضطر لإستخدام ما يسمى بـ parcelable.
بداية ما هو الـ parcelable, هو interface يعمل كعمل الـ Serializable في جافا لكن مخصص لأندرويد, يعمل على تحويل الـ object إلى byte واستعادته كـ object مرة أخرى وفي هذه الدرس سنتكلم عنه وعن الية التعامل معه.
لنفرض أن لدينا Student class
} public class Student
;private String name
;private int id
} (public Student(String name, int id
this.name = name
;this.id = id
{
} ()public String getName
;return name
{
} (public void setName(String name
;this.name = name
{
} ()public int getId
;return id
{
} (public void setId(int id
;this.id = id
{
{
لدينا two Activities الأولى MainActivity والثانية ShowStudentActivity, سنحاول نقل object واحد ومن ثم نقل list of object.
سنقوم في هذا الدرس بعمل ثلاثة اجزاء :
- نقوم بعمل implementation لـ Parcelable
- نقوم بتمرير object
- نقوم بتمرير list of object
لنبدأ بعمل implementation لـ Parcelable
} public class Student implements Parcelable
;private String name
;private int id
} (public Student(String name, int id
;this.name = name
;this.id = id
{
} (protected Student(Parcel in
;()name = in.readString
;()id = in.readInt
{
} ()<public static final Creator<Student> CREATOR = new Creator<Student
Override@
} (public Student createFromParcel(Parcel in
;(return new Student(in
{
Override@
} (public Student[] newArray(int size
;[return new Student[size
{
;{
} ()public String getName
;return name
{
} (public void setName(String name
;this.name = name
{
} ()public int getId
;return id
{
} (public void setId(int id
;this.id = id
{
Override@
} ()public int describeContents
;()return hashCode
{
Override@
} (public void writeToParcel(Parcel dest, int flags
;(dest.writeString(name
;(dest.writeInt(id)
{
{
بداية قمنا بعمل implementation لـ Parcelable, ثم override لدالتين, الأولى describeContents والتي ترجع hash code الخاص بـ class, والثانية writeToParcel تحول data members إلى Parcel class, فنستخدم دوال Parcel class لتخزين بياناتنا, وهنا ينبغي الانتباه لترتيب data members عند الكتابة والقراءة حيث أنه في حال ما حدث تغيير في الترتيب قد يكون هناك crash لتطبيق.
Override@
} ()public int describeContents
;()return hashCode
{
Override@
} (public void writeToParcel(Parcel dest, int flags
;(dest.writeString(name
;(dest.writeInt(id)
{
بعد ذلك قمنا ببناء static field يسمى CREATOR وهو يستخدم من النظام لاستعادة البيانات – unparcel – , بداخلة دالتين أخرتين الأولى createFromParcel وهي تستخدم لإعادة بناء الـ object, ونلاحظ بداخلها استدعاء لـ constructor يستقبل parcel object لذلك سنقوم ببناء هذا constructor لاحقا, الدالة الثانية newArray وهي تستدعى في حال كان لديك مصفوفة – array – من الـ Parcelable ثم تستدعي الدالة الأولى createFromParcel عند بناء كل عنصر داخل هذه المصفوفة.
} ()<public static final Creator<Student> CREATOR = new Creator<Student
Override@
} (public Student createFromParcel(Parcel in
;(return new Student(in
{
Override@
} (public Student[] newArray(int size
;[return new Student[size
{
;{
كما ذكرنا أن دالة createFromParcel تستدعي constructor يستقبل parcel object, ولهذا سنقوم ببنائه, وكما ذكرنا أيضا أن الترتيب مطلوب كما, قمنا بكتابة name أولا ثم id, سنقرأ بنفس الترتيب كالتالي
} (protected Student(Parcel in
;()name = in.readString
;()id = in.readInt
{
وبهذا يكون لدينا class نستطيع نقول بياناته بين الـ activity بشكل بسيط وسلس
سنقوم الان بنقل object واحد من هذا class إلى Activity أخرى, كما هو معلوم التنقل بين الـ activites يكون دائما بإستخدام Intent, ولنقل البيانات نستخدم الدوال المساعدة في عملية النقل putExtra, هذه الدالة تستيع التعامل مع عدة انواع من المتغيرات – overloaded method – منها ال Parcelable, كما نلاحظ من داخل Intent class
} (public @NonNull Intent putExtra(String name, Parcelable value
} (if (mExtras == null
;()mExtras = new Bundle
{
;(mExtras.putParcelable(name, value
;return this
{
لذا فيمكننا إرسال object كالتالي
;(Student student = new Student(“Kream”,16
;(Intent i = new Intent(this,ShowStudentActivity.class
;(i.putExtra(“Key”,student
;(startActivity(i
واستقباله في ShowStudentActivity بهذه الطريقة
;(“Student student = getIntent().getParcelableExtra(“Key
سنقوم الان بنقل ArrayList من نفس الـ class بنفس الطريقة
;()<>ArrayList<Student> students = new ArrayList
;((students.add(new Student(“Ali”,18
;((students.add(new Student(“Ahmed”,19
;((students.add(new Student(“Adel”,20
;((students.add(new Student(“Khaled”,23
;((students.add(new Student(“Kream”,16
;(Intent i = new Intent(this,ShowStudentActivity.class
;(i.putParcelableArrayListExtra(“students”, students
;(startActivity(i
ثم استعادتها في الـ Activity الأخرى
;(“ArrayList<Student> students = getIntent().getParcelableArrayListExtra(“students