[PrivacyTools] [Free Software Foundation] [GNU Operating System]

مقدمة الى الخدمات و برمجة الخدمة غير المقيدة | Started\Unbound service

بسم الله الرحمن الرحيم , السلام عليكم ورحمه الله وبركاته .

في هذا الموضوع ساكتب لكم مقدمة عن الخدمات في نظام الأندرويد وطريقة استخدامها في البرمجة .


فهرس الموضوع :

  • أولا ما هي الخدمة (Service) .
  • ثانيا ما فائدة الخدمات في الأندرويد .
  • ثالثا أنواع الخدمات والفرق بينها .
  • رابعا فهم دورة حياة الخدمات غير المقيدة .
  • خامسا تطبيق عملي على دورة حياة الخدمات غير المقيدة .
  • سادسا مثال مفيد على الخدمات غير المقيدة .
  • سابعا المصادر والمراجع اللتي تم استخدماها .

أولا : ما هي الخدمة (Service) ؟

الخدمة : هي مكون من مكونات التطبيق يمكنك ان تقوم بانشاء عمليات في الخلفية بشكل منفصل عن واجهة التطبيق الأساسية التي يتعامل معها المستخدم .
لذلك يمكنك تشبيهها بالعامل اللذي يعمل من وراء الكواليس لتنفيذ مهمة معينة .


ثانيا : ما فائدة الخدمات في الاندرويد ؟

تمكنك الخدمات من القيام بعمليات بشكل مستمر لفترة حتى بعد اغلاق التطبيق فهي تعمل تقريبا بشكل منفصل تقريبا عن التطبيق .
تخيل مثلا انك قمت ببرمجة تطبيق لتحميل بعض الملفات من الانترنت ، هل من المنطقي أن يتوقف التحميل وتتوقف كل العمليات التي كانت تجري اذا خرج المستخدم من التطبيق ؟
بالطبع لا وهنا تظهر الفائدة العملية للخدمات .

ثالثا : أنواع الخدمات .

يوجد نوعان من الخدمات في أندرويد :

  • خدمات غير مقيدة (Unbound / Started Services)
  • خدمات مقيدة (Bound Services)

و فيما يأتي الفرق بينهما :

1-الخدمات غير المقيدة هي خدمات يتم استدعاؤها من الـ Activity وايقافها منها ايضا لتقوم بعمليات معينة بشكل منفصل عن الـ Activity

2-الخدمات المقيدة هي خدمات مرتبطة بالـ Activity حيث يمكن معرفة تقدم سير العمليات مثلا لو كان البرنامج عبارة عن برنامج يقوم بتحميل ملف من الانترنت ستتمكن من معرفة النسبة المئوية لتقدم التحميل أو حالة التحميل ان كان متوقفا او مستمرا وغيرها من العمليات من خلال الـ Activity وكذلك بالنسبة لباقي العمليات .

خلاصة : الخدمات المقيدة خدمات تستطيع معرفة معلومات اكثر عنها من خلال الواجهة التي يتعامل معها المستخدم على عكس غير المقيدة


رابعا : فهم دورة حياة الخدمة الغير مقيدة .

الصورة تم اخذها من موقع Android Developers

لاحظ تسلسل العمليات في الصورة :

  • الحدث onCreate() هو أول حدث ويتم عند انشاء الـ Service
  • الحدث onStartCommand() كان سابقا يسمى في الاصدارات القديمة من أندرويد onStart() وهو حدث يتم عند بدء العملية (العمليات تحدث في المربع الاصفر في الصورة واللذي يحتوي هذا الحدث)
  • الحدث onDestroy حدث يتم عند توقف عمل الخدمة وانتهاءها أو عندما يقرر المستخدم ايقافها

خامسا : تطبيق عملي على دورة حياة الخدمات غير المقيدة .

بعد فهم الخدمات غير المقيدة نظريا نأتي الآن الى الجزء العملي ، قم بانشاء مشروع جديد باسم Service Example وقم باضافة كلاس من نوع Service (الصورة التالية ستوضح لك الطريقة) :

ستظهر لك نافذة لاختيار الاسم اختر الاسم اللذي تريده ثم اضغط Finish (قد تكون بعض الخطوات مختلفة بحسب بيئة التطوير اللتي تعمل عليها) .

الآن يجب اضافة الـ Service إلى ملف الـ AndroidManifest.xml (تجاوز هذه الخطوة ان كنت من مستخدمي Android Studio فهو يضيفها تلقائيا)

في داخل tag الـ application قم باضافة هذا السطر :
<service android:name=".MyService"/>

الان بالعودة الى كلاس الـ Service قم باضافة دالة onStartCommand بهذا الشكل :

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

return START_STICKY;

}

لاحظ أنني قمت بتغيير نوع الارجاع عن النوع الافتراضي وجعلته START_STICKY وهذا سينقلنا الى سؤال اخر وهو لم وضعت هذا الثابت وما الفرق بينه وبين START_NOT_STICKY

أولا عليك ان تعرف أن نظام الاندرويد قد يغلق احيانا بعض التطبيقات وربما الخدمات اذا احتاج الى ذاكرة اكبر وهذا يتم بحيث الخروج بأقل الخسائر والتقليل من نسبة جعل الجهاز يتجمد بسبب نقص الذاكرة ، ولذلك نستخدم هذين الثابتين لاصدار امر في تلك الحالة :

  • START_STICKY تطلب من النظام استدعاءها مجددا عند توفر المزيد من الذاكرة الكافية لتشغيلها
  • START_NOT_STICKY عند وضعها لن تطلب من النظام استدعاءها مجددا عند توفر المزيد من الذاكرة

الآن قم بكتابة الدالة onStartCommand بالاضافة الى دالتي onCreate و onDestroy .

للتعرف الى دورة حياة الـ Service بشكل عملي قم بتعريف متغير من نوع String باسم tag في الكلاس ولتكن قيمته تساوي “EVENT” بالشكل الآتي :
String tag = "EVENT"

وضع هذا الكود في كل دالة من الدوال اللتي ذكرتها اعلاه :
Log.d(tag,"EVENTNAME")

استبدل كلمة EVENTNAME باسم الدالة اللتي وضعت فيها الكود

الآن لننتقل الى الـ Activity الرئيسية وضع فيها 2 من الـ Button ولا تنسى ان تضع دالة onClick لكل واحد منهما قم بتغيير اسم الأول ليصبح start واسم الثاني ليصبح stop
انظر الى كود الـ layout :

<?xml version="1.0" encoding="utf-8"?>
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="start"
    android:id="@+id/button"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="138dp" />
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="stop"
    android:id="@+id/button2"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true" />

في الحدث onClick للزر start قم بوضع الاكواد الآتية :

Intent i = new Intent(this,MyService.class);
startService(i);

في الحدث onClick للزر stop قم بوضع الاكواد الآتية :

Intent i = new Intent(this,MyService.class);
stopService(i);

بالاكواد السابقة تقوم بانشاء Intent واللذي يستخدم في نقل الرسائل بين اجزاء التطبيق أو التطبيق مع التطبيقات الاخرى كما يفترض انك تعرف
اما الدوال اللتي تلحقها فهي دوال لتشغيل وايقاف الـ service

الآن قم بتشغيل البرنامج ولاحظ قائمة log أو قائمة Android monitor

لاحظ انك عند الضغط على الزر start ستعلمك قائمة log بان الحدث onCreate قد عمل ومن بعده مباشرة يأتي onStartCommend وعند الضغط على الزر stop سيعلمك ان الحدث onDestroy قد تم تنفيذ محتوياته


سادسا : مثال مفيد على استخدام الـ Services

سنقوم بهذا المثال بالاعتماد كثيرا على المثال السابق وسيكون هذا المثال عبارة عن برنامج بسيط يشغل ملف صوتي في الـResorces يستمر عمله حتى بعد اغلاق البرنامج ويتم ايقافه عند الضغط على الزر stop

أولا قم بإنشاء مجلد باسم raw داخل مجلد res وانقل اليه أي ملف صوتي تريد التجربة عليه .

الآن عدل دوال كلاس الـ Service لتصبح كالتالي(انتبه لتعريف مكتبة الصوتيات في الكلاس) :

MediaPlayer mediaPlayer = null;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer = MediaPlayer.create(this,R.raw.sound);
mediaPlayer.start();
return START_STICKY;
}

@Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}

الآن قم بتشغيل البرنامج ، عند الضغط على زر start سيبدأ الملف الصوتي بالعمل لو خرجت من البرنامج لن يتوقف عن العمل لأنك شغلته بداخل service والآن جرب ان تدخل البرنامج وتضغط stop وسترى كيف سيتوقف تشغيل الملف الصوتي :wink:


مصادر ومراجع مفيدة تم استخدامها والرجوع اليها لضمان صحة المعلومات في هذا الشرح :

7 Likes