دورة حياة الاندرويد

Android-Activity-Lifecycle

نظام الاندرويد مبني بطريقة تمكنه من التحكم في دورة حياة اي تطبيق يعمل من خلاله هذا يعني ان لديه القدرة على قتل اي تطبيق او عملية خاملة في النظام وذلك لتوفير مساحة في الـ Ram, فـ اي Activity تكون حالتها onStop ربما وبدون سابق انذار تقتل وتفرغ من الرام وذلك لان النظام يعتبرها عملية خاملة, وبالتالي ربما واجهتك كمطور احد المشاكل التالية:

  • في حالة قام المستخدم بعمل Rotate للجهاز فان الاكتفتي تفقد البيانات الموجودة بداخلها وخاصة قيم المتغيرات مع ان المستخدم لم يقم بايقاف البرنامج!!
  • في بعض الحالات التي تقوم فيها باستدعاء Activity من تطبيق اخر وتنتظر البيانات في ميثود onActivityResult تتفاجئ بأن الـ Activity فقدت البيانات!

دورة حياة الـ Activity وتخزين واسترجاع الـ State

عندما تقوم الاكتفتي باستدعاء onSaveInstanceState فإن الاكتفتي مباشرة تقوم بتجميع جميع بيانات الـ Viwe’s الموجودة داخل الـ Activity وتقوم بتخزينها داخل Bundle في ذاكرة الجهاز وذلك عند ايقاف الـ Activity, وفي نفس الحالة ان تم استدعاء الـ Activity من جديد يقوم الاندرويد بـ استدعاء الـ Bundle الذي قام بتخزينه وذلك عن طريق ميثود onRestoreInstanceState.

ستقوم ميثود onRestoreInstanceState باسترجاع حالة كل view عن طريق الـ id الذي تخزنت فيه.

public static class SavedState extends BaseSavedState {
    public static final Creator<TextView.SavedState> CREATOR = null;
    SavedState() {
        super((Parcelable)null);
        throw new RuntimeException("Stub!");
    }
    public void writeToParcel(Parcel out, int flags) {
        throw new RuntimeException("Stub!");
    }
    public String toString() {
        throw new RuntimeException("Stub!");
    }
}

لنرجع الان الى المشكلتين التي ذكرناها في بداية المقالة, فكما شاهدنا ان بعض البيانات والمتغيرات الموجودة في الـ Activiy اختفت وضاعت وذلك بسبب ان الاكتفتي تغيرت حالتها الـ onStop وبالتالي قام الاندرويد بافراغها من الذاكرة وذلك يعني ان جميع البيانات الموجودة في الـ Activity انحذفت, فالحل لهذه المشكلة هو باستخدام اكثر من طريقة, الاولى واللي البعض يستخدمها وتعتبر نوعاً ما خاطئة, هو انك تخزن المتغيرات والبيانات في الـ SharedPrefrance في ميثود onStop وتقرا البيانات من جديد في ميثود onStart ولكن نقول من جديد ان الطريقة هذه خاطئة و الحل الافضل والطريقة المتبعة هي ان كل اكتفتي لها Bundle خاص بها تقدر تخزن فيه اي بيانات على مستوى الـ Activity .

طريقة عملها

قبل كل شي لازم نعدل شوي على الـ LifeCycle الخاص بالاندرويد ونضيف لها onSaveInstanse وتستدعى قبل onPause ووضيفتها هي تخزين الـ Bundle الخاص بالـ Acitvity, والميثود الثانيه هي OnResotreInstanse وتستدعى بعد onCreate وتقوم باسترجاع الـ Bundle الموجود فيه البيانات التي قمت بتخزينها.

طريقة الحفظ والاسترجاع

public class MainActivity extends AppCompatActivity {
 
    // These variable are destroyed along with Activity
    private int someVarA;
    private String someVarB;
 
    ...
 
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("someVarA", someVarA);
        outState.putString("someVarB", someVarB);
    }
 
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        someVarA = savedInstanceState.getInt("someVarA");
        someVarB = savedInstanceState.getString("someVarB");
    }
 
}