انشاء الـ Bound Service
بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته
في الدرسين السابقين رأينا طريقة انشاء الـ Started Service والـ Intent Service. في هذا الدرس سنرى طريقة تحويلهم او بالاحرى انشاء النوع الـ Bound Service.
طريقة عمل هذة الكلاس:
هذا النوع عباره عن Service عاديه كالـ Started Service و IntentService, ولكن الاختلاف هنا هو استخدام الدالة onBind() لإرجاع عنصر لاصق (binder) بعد انشائه بداخلها وهنا تتحول الى هذا النوع. وللمخاطبه بين هذا النوع والمكون الذي قام بتشغيلها(كالـ Activity) نحتاج الى انشاء عنصر من نوع Service Connection في المكون نفسه حتى تستطيع التخاطب معها.
نقاط يجب عليك مراعاتها عند العمل مع هذا النوع من الخدمات
- تعمل في الخيط الرئيسي (Main/UI Thread) لذلك يجب عليك مراعاة عدم استخدامها للمهام الثقيلة.
- نستطيع تشغيلها من خلال المكونات التالية: Activities و Content Provider و Service, ولكننا لانستطيع استخدام المكون Broadcast لتشغيلها.
- تلتصق (Bound) بالمكون الذي قام بتشغيلها. ونستطيع كذلك لصقها باكثر من مكون واحد.
- تستطيع التخاطب كـ ارسال واستقبال وتبادل البيانات والنتائج مع المكون الملتصقه به. اي اننا لانحتاج للتعامل مع ResultReceiver او Local Broadcast (نحتاج فقط لإنشاء ServiceConnection في المكون).
- نستطيع تشبيهها بالخادم (Server) والمكون الذي قام بتشغيلها والتصق بها نستطيع تشبيهه بالعميل (Client).
- تقوم باطفاء نفسها عندما يتم انهاء جميع المكونات الملتصقة بهم.
الهدف
انشاء كلاس Service تقوم بأخد معطيان رقمان ثم تقوم بجمعهم وطباعة الناتج في الـ Log.
طريقة انشاء كلاس من نوع الـ Started Service
- انشاء كلاس جديدة.
- عمل Extends لكلاس الـ Service.
- اضافتها الى ملف الـ Manifest.xml.
- نعمل Override للدوال:
- onBind() حتى نقوم بإرجاع هذة الكلاس لإلصاقها للمكون المراد.
- انشاء عنصر من نوع Binder في داخل هذه الكلاس للصقها مع المكون.
- انشاء عنصر من نوع ServiceConnection لإنشاء التخاطب مع المكون الذي ستلتصق به.
الخطوات
انشاء كلاس جديدة وجعلها تعمل extends لكلاس الـ IntentService:
public class MyBoundService extends Service {}
اضافتها الى ملف الـ Manifest.xml:
<service android:name=".service.MyBoundService"/>
انشاء كلاس داخليه من نوع Binder وبها داله لإرجاع كلاس هذه الـ Service:
public class MyBinder extends Binder {
public MyBoundService getService() {
return MyBoundService.this;
}
}
عمل حقل للـ Binder:
private MyBinder mMyBinder = new MyBinder();
عمل Override للداله onBind ونقوم بإنجاز هذه المهام بداخلها: الشفره المراد تشغيلها, و حفظ الشفره في الحقل عن طريق Setter واخيراً تقوم بارجاع حقل الـ Binder:
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: Called.");
int firstNumber = intent.getIntExtra(Constant.FIRST_NUMBER, -1);
int secondNumber = intent.getIntExtra(Constant.SECOND_NUMBER, -2);
int resultNumber = firstNumber + secondNumber;
mMyBinder.getService().setResult(resultNumber);
return mMyBinder;
}
الكلاس كامله:
public class MyBoundService extends Service {
private static final String TAG = "MyBoundService";
private MyBinder mMyBinder = new MyBinder();
private int mResult = -1;
// Our Binder Class
public class MyBinder extends Binder {
public MyBoundService getService() {
return MyBoundService.this;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: Called.");
int firstNumber = intent.getIntExtra(Constant.FIRST_NUMBER, -1);
int secondNumber = intent.getIntExtra(Constant.SECOND_NUMBER, -2);
int resultNumber = firstNumber + secondNumber;
mMyBinder.getService().setResult(resultNumber);
return mMyBinder;
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
private void setResult(int resultNumber) {
mResult = resultNumber;
}
// Used to send bound
public int getResult() {
return mResult;
}
}
قمنا باستقبال البيانات من الـ Activity من خلال الـ Intent في الداله onBind. ثم قمنا بحفظ النتيجه باستخدام Setter الى الحقل mResult. لاحظ ايضاً وجود الداله getResult من نوع Getter لهذا الحقل, حيث اننا سنستخدمها في الـ Activity للحصول على النتيجه.
طريقة نقل البيانات: تقنية الـ Bound تسمح لنا بالدخول الى دوال الـ Getter الموجوده في الـ Service من المكون الملتصقه به (في مثالنا المكون هو Activity).
في كلاس الـ Actiivty:
نقوم بإنشاء الحقول:
private TextView mResultTextView;
private boolean isBound = false;
private MyBoundService mMyBoundService;
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
isBound = true;
MyBoundService.MyBinder myBinder = (MyBoundService.MyBinder) service;
mMyBoundService = myBinder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
}
};
- الحقل الاول هو عباره عن الـ View.
- الحقل الثاني هو عباره عن boolean لنحدد هل السيرفس في حاله Bound ام لا.
- الحقل الثالث MyBoundService هو حقل للكلاس السيرفس التي انشئناها.
- اما الـ ServiceConnection فهو وسيلة الربط واستلام المعلومات من كلاس الـ Bound الى هذه الـ Activity.
- الداله onServiceConnected تعمل عند عمل Bound للسيرفر. لذلك قمنا بجعل عنصر الـ Bound الى true. وايضاً قمنا بعمل init للحقل mMyBoundService بداخلها باستخدام الـ Binder الذي انشئناه سابقاً.
عمل Bound للسيرفس:
نقوم بعمل Override للداله onStart وننشئ بداخلها الـ Intent التي ستعمل Bound كالتالي:
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(Main6Activity.this, MyBoundService.class);
intent.putExtra(Constant.FIRST_NUMBER, 10);
intent.putExtra(Constant.SECOND_NUMBER, 20);
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
}
لاحظ استخدمنا bindService لعمل Bound لهذه السيرفس (وليس startService) والتي تأخد عنصر ServiceConnection و نوع الـ Bound (هنا اخترنا النوع BIND_AUTO_CREATE).
نقوم بعمل Override للداله onDestroy لإزالتها حتى لاتحدث مشاكل في الذاكرة:
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
}
حل تشغيل مهمه طويله على هذا النوع
من الافضل عدم استخدامها للمهام الطويله او قم باستخدام احد انماط الخيوط الحاسوبية كما اتى شرحهم في الدروس السابقه.
في هذا الدرس رأينا طريقة انشاء الخدمة من نوع الـ Bound Service وكيفية انشاء ServiceConnection لربطها مع الكون الذي قام بتشغيلها, حتى تستطيع نقل البيانات والنتائج اليه بكل سهوله ويسر. في الدرس القادم سنرى طرق مساعدة لجعل الـ Started Service و الـ Intent Service تستطيع نقل البيانات والنتائج الى المكون الذي قام بتشغيلها.
رابط الكلاسات المستخدمه في هذا الدرس
- تم استخدام MyBoundService.java في Main6Activity.java.
للحصول على رابط المشروع راجع درس المقدمة.
المصادر والمراجع
- Bound services overview | Android Developers.
- IBinder | Android Developers.
- راجع الدرس: تعرف على الـ Services.
للمزيد راجع درس المقدمة.
نهاية الدرس
لاتنسى تتبع الدرس والدورة كذلك لإشعارك عندما يتم التعديل على المتحوى او اضافة المزيد من المعلومات. ايضاً لاتنسى الاعجاب بالدرس ومشاركته مع الاخرين.
محتوى الدورة
الكلمات الدليلية
عن الدرس
0 إعجاب |
1 متابع |
0 مشاركة |
2315 مشاهدات |
منذ 5 سنوات |
التعليقات (0)
لايوجد لديك حساب في عالم البرمجة؟
تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !