الـ Parcelable في أندرويد

3zcsمنذ 6 سنوات

بسم الله الرحمن الرحيم 

لإرسال البيانات بين 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.

سنقسم هذه المقالة إلى ثلاثة أقسام:

  1. نقوم بعمل implementation لـ Parcelable
  2. نقوم بتمرير object
  3. نقوم بتمرير 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 بهذه الطريقة 


public class ShowStudentActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_student);
        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 الأخرى 


public class ShowStudentActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_student);
        ArrayList<Student> students = getIntent().getParcelableArrayListExtra("students");
    }
}

 

أندرويد ستديو له عدد من الإختصارات تسهل عمل implementation لـ Parcelable استعرضتها في هذا الفيديو: 

 

إلى هنا نكون قد وصلنا إلى نهاية هذه المقالة, والسلام عليكم ورحمة الله وبركاته 

 

المصادر: 

https://www.survivingwithandroid.com/2012/09/passing-data-between-activities-2.html

https://stackoverflow.com/questions/22037801/parcelable-what-is-newarray-for

https://developer.android.com/reference/android/os/Parcel.html

 

كلمات دليلية:
4
إعجاب
5811
مشاهدات
0
مشاركة
0
متابع
متميز
محتوى رهيب

التعليقات (0)

لايوجد لديك حساب في عالم البرمجة؟

تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !