সেবা ওভারভিউ

একটি Service হল একটি অ্যাপ্লিকেশন উপাদান যা ব্যাকগ্রাউন্ডে দীর্ঘস্থায়ী ক্রিয়াকলাপ সম্পাদন করতে পারে। এটি একটি ব্যবহারকারী ইন্টারফেস প্রদান করে না. একবার শুরু হলে, ব্যবহারকারী অন্য অ্যাপ্লিকেশনে স্যুইচ করার পরেও একটি পরিষেবা কিছু সময়ের জন্য চলতে থাকতে পারে। অতিরিক্তভাবে, একটি উপাদান একটি পরিষেবার সাথে যোগাযোগ করতে এবং এমনকি আন্তঃপ্রক্রিয়া যোগাযোগ (IPC) সঞ্চালনের জন্য আবদ্ধ হতে পারে। উদাহরণস্বরূপ, একটি পরিষেবা নেটওয়ার্ক লেনদেন পরিচালনা করতে পারে, সঙ্গীত চালাতে পারে, ফাইল I/O সঞ্চালন করতে পারে, বা একটি বিষয়বস্তু প্রদানকারীর সাথে ইন্টারঅ্যাক্ট করতে পারে, সবকিছুই পটভূমি থেকে।

সতর্কতা: একটি পরিষেবা তার হোস্টিং প্রক্রিয়ার মূল থ্রেডে চলে; পরিষেবাটি তার নিজস্ব থ্রেড তৈরি করে না এবং আপনি অন্যথায় উল্লেখ না করলে আলাদা প্রক্রিয়ায় চলে না । অ্যাপ্লিকেশন নট রেসপন্ডিং (ANR) ত্রুটিগুলি এড়াতে আপনাকে পরিষেবার মধ্যে একটি পৃথক থ্রেডে ব্লকিং অপারেশন চালানো উচিত।

সেবার প্রকারভেদ

এই তিনটি ভিন্ন ধরনের পরিষেবা:

ফোরগ্রাউন্ড

একটি ফোরগ্রাউন্ড পরিষেবা এমন কিছু অপারেশন করে যা ব্যবহারকারীর কাছে লক্ষণীয়। উদাহরণস্বরূপ, একটি অডিও অ্যাপ একটি অডিও ট্র্যাক চালানোর জন্য একটি ফোরগ্রাউন্ড পরিষেবা ব্যবহার করবে। ফোরগ্রাউন্ড পরিষেবাগুলি অবশ্যই একটি বিজ্ঞপ্তি প্রদর্শন করবে৷ ব্যবহারকারী অ্যাপের সাথে ইন্টারঅ্যাক্ট না করলেও ফোরগ্রাউন্ড পরিষেবাগুলি চলতে থাকে।

আপনি যখন একটি ফোরগ্রাউন্ড পরিষেবা ব্যবহার করেন, আপনাকে অবশ্যই একটি বিজ্ঞপ্তি প্রদর্শন করতে হবে যাতে ব্যবহারকারীরা সক্রিয়ভাবে সচেতন থাকে যে পরিষেবাটি চলছে৷ এই বিজ্ঞপ্তিটি বাতিল করা যাবে না যদি না পরিষেবাটি হয় বন্ধ করা হয় বা অগ্রভাগ থেকে সরানো হয়৷

আপনার অ্যাপে ফোরগ্রাউন্ড পরিষেবাগুলি কীভাবে কনফিগার করবেন সে সম্পর্কে আরও জানুন।

দ্রষ্টব্য: WorkManager API কার্যগুলি নির্ধারণের একটি নমনীয় উপায় অফার করে এবং প্রয়োজনে এই কাজগুলিকে অগ্রভাগের পরিষেবা হিসাবে চালাতে সক্ষম৷ অনেক ক্ষেত্রে, ফোরগ্রাউন্ড পরিষেবাগুলি সরাসরি ব্যবহার করার চেয়ে WorkManager ব্যবহার করা ভাল৷

পটভূমি
একটি ব্যাকগ্রাউন্ড পরিষেবা এমন একটি অপারেশন করে যা ব্যবহারকারীর দ্বারা সরাসরি লক্ষ্য করা যায় না। উদাহরণস্বরূপ, যদি একটি অ্যাপ তার স্টোরেজ কমপ্যাক্ট করতে একটি পরিষেবা ব্যবহার করে, তবে এটি সাধারণত একটি ব্যাকগ্রাউন্ড পরিষেবা হবে।

দ্রষ্টব্য: যদি আপনার অ্যাপটি এপিআই লেভেল 26 বা তার বেশি টার্গেট করে, তবে অ্যাপটি ফোরগ্রাউন্ডে না থাকলে সিস্টেম ব্যাকগ্রাউন্ড পরিষেবা চালানোর উপর বিধিনিষেধ আরোপ করে। বেশিরভাগ পরিস্থিতিতে, উদাহরণস্বরূপ, আপনার পটভূমি থেকে অবস্থানের তথ্য অ্যাক্সেস করা উচিত নয়৷ পরিবর্তে, WorkManager ব্যবহার করে কাজের সময়সূচী করুন

আবদ্ধ
একটি পরিষেবা আবদ্ধ হয় যখন একটি অ্যাপ্লিকেশন উপাদান bindService() কল করে এটির সাথে আবদ্ধ হয়। একটি আবদ্ধ পরিষেবা একটি ক্লায়েন্ট-সার্ভার ইন্টারফেস অফার করে যা উপাদানগুলিকে পরিষেবার সাথে ইন্টারঅ্যাক্ট করতে, অনুরোধ পাঠাতে, ফলাফল পেতে এবং এমনকি ইন্টারপ্রসেস কমিউনিকেশন (আইপিসি) সহ সমস্ত প্রক্রিয়া জুড়ে তা করতে দেয়। একটি আবদ্ধ পরিষেবা কেবল ততক্ষণ পর্যন্ত চলে যতক্ষণ অন্য অ্যাপ্লিকেশন উপাদান এটিতে আবদ্ধ থাকে। একাধিক উপাদান একবারে পরিষেবার সাথে আবদ্ধ হতে পারে, কিন্তু যখন সেগুলি সমস্ত বন্ধ করে দেয়, পরিষেবাটি ধ্বংস হয়ে যায়।

যদিও এই ডকুমেন্টেশনটি সাধারণত শুরু এবং আবদ্ধ পরিষেবাগুলিকে আলাদাভাবে আলোচনা করে, আপনার পরিষেবা উভয় ভাবেই কাজ করতে পারে-এটি শুরু করা যেতে পারে (অনির্দিষ্টকালের জন্য চালানোর জন্য) এবং বাঁধাই করার অনুমতিও দেওয়া যেতে পারে৷ আপনি কয়েকটি কলব্যাক পদ্ধতি প্রয়োগ করেন কিনা তা কেবল একটি বিষয়: onStartCommand() উপাদানগুলিকে এটি শুরু করার অনুমতি দেওয়ার জন্য এবং onBind() বাইন্ডিংয়ের অনুমতি দেওয়ার জন্য।

আপনার পরিষেবাটি শুরু, আবদ্ধ বা উভয়ই হোক না কেন, যেকোন অ্যাপ্লিকেশন উপাদান পরিষেবাটি ব্যবহার করতে পারে (এমনকি একটি পৃথক অ্যাপ্লিকেশন থেকেও) একইভাবে যে কোনও উপাদান কোনও কার্যকলাপ ব্যবহার করতে পারে—একটি Intent দিয়ে শুরু করে৷ যাইহোক, আপনি ম্যানিফেস্ট ফাইলে পরিষেবাটিকে ব্যক্তিগত হিসাবে ঘোষণা করতে পারেন এবং অন্যান্য অ্যাপ্লিকেশনগুলির অ্যাক্সেস ব্লক করতে পারেন৷ ম্যানিফেস্টে পরিষেবা ঘোষণা করার বিষয়ে বিভাগে এটি আরও আলোচনা করা হয়েছে।

একটি পরিষেবা এবং একটি থ্রেড মধ্যে নির্বাচন

একটি পরিষেবা কেবলমাত্র একটি উপাদান যা ব্যাকগ্রাউন্ডে চলতে পারে, এমনকি যখন ব্যবহারকারী আপনার অ্যাপ্লিকেশনের সাথে ইন্টারঅ্যাক্ট করছে না, তাই আপনার প্রয়োজন হলেই একটি পরিষেবা তৈরি করা উচিত।

যদি আপনাকে অবশ্যই আপনার প্রধান থ্রেডের বাইরে কাজ করতে হবে, কিন্তু শুধুমাত্র যখন ব্যবহারকারী আপনার অ্যাপ্লিকেশনের সাথে ইন্টারঅ্যাক্ট করছে, তাহলে আপনার পরিবর্তে অন্য অ্যাপ্লিকেশন উপাদানের প্রসঙ্গে একটি নতুন থ্রেড তৈরি করা উচিত। উদাহরণস্বরূপ, যদি আপনি কিছু সঙ্গীত বাজাতে চান, কিন্তু শুধুমাত্র আপনার কার্যকলাপ চলাকালীন, আপনি onCreate() এ একটি থ্রেড তৈরি করতে পারেন, এটি onStart() এ চালানো শুরু করতে পারেন এবং onStop() এ এটি বন্ধ করতে পারেন। এছাড়াও ঐতিহ্যগত Thread ক্লাসের পরিবর্তে java.util.concurrent প্যাকেজ বা Kotlin coroutines থেকে থ্রেড পুল এবং নির্বাহক ব্যবহার করার কথা বিবেচনা করুন। ব্যাকগ্রাউন্ড থ্রেডে এক্সিকিউশন সরানোর বিষয়ে আরও তথ্যের জন্য Android নথিতে থ্রেডিং দেখুন।

মনে রাখবেন যে আপনি যদি একটি পরিষেবা ব্যবহার করেন, তবে এটি এখনও আপনার অ্যাপ্লিকেশনের প্রধান থ্রেডে ডিফল্টরূপে চলে, তাই যদি এটি নিবিড় বা ব্লকিং ক্রিয়াকলাপ সম্পাদন করে তবে পরিষেবাটির মধ্যে আপনার এখনও একটি নতুন থ্রেড তৈরি করা উচিত।

বুনিয়াদি

একটি পরিষেবা তৈরি করতে, আপনাকে অবশ্যই Service একটি সাবক্লাস তৈরি করতে হবে বা এর বিদ্যমান সাবক্লাসগুলির একটি ব্যবহার করতে হবে৷ আপনার বাস্তবায়নে, আপনাকে অবশ্যই কিছু কলব্যাক পদ্ধতি ওভাররাইড করতে হবে যা পরিষেবা জীবনচক্রের মূল দিকগুলি পরিচালনা করে এবং এমন একটি ব্যবস্থা প্রদান করে যা উপযুক্ত হলে উপাদানগুলিকে পরিষেবার সাথে আবদ্ধ হতে দেয়৷ এই হল সবচেয়ে গুরুত্বপূর্ণ কলব্যাক পদ্ধতি যা আপনার ওভাররাইড করা উচিত:

onStartCommand()
সিস্টেমটি startService() কল করে এই পদ্ধতিটি চালু করে যখন অন্য একটি উপাদান (যেমন একটি কার্যকলাপ) পরিষেবাটি শুরু করার অনুরোধ করে। যখন এই পদ্ধতিটি কার্যকর হয়, পরিষেবাটি শুরু হয় এবং অনির্দিষ্টকালের জন্য পটভূমিতে চলতে পারে। আপনি যদি এটি বাস্তবায়ন করেন, তাহলে stopSelf() বা stopService() কল করে পরিষেবাটির কাজ শেষ হলে সেটি বন্ধ করা আপনার দায়িত্ব৷ আপনি যদি শুধুমাত্র বাইন্ডিং প্রদান করতে চান তবে আপনাকে এই পদ্ধতিটি বাস্তবায়ন করতে হবে না।
onBind()
সিস্টেমটি bindService() কল করে এই পদ্ধতিটি চালু করে যখন অন্য একটি উপাদান পরিষেবার সাথে আবদ্ধ হতে চায় (যেমন RPC সম্পাদন করতে)। আপনার এই পদ্ধতির বাস্তবায়নে, আপনাকে অবশ্যই একটি ইন্টারফেস প্রদান করতে হবে যা ক্লায়েন্টরা IBinder ফেরত দিয়ে পরিষেবার সাথে যোগাযোগ করতে ব্যবহার করে। আপনি সবসময় এই পদ্ধতি বাস্তবায়ন করতে হবে; যাইহোক, যদি আপনি বাইন্ডিংয়ের অনুমতি দিতে না চান, তাহলে আপনার নাল ফেরত দেওয়া উচিত।
onCreate()
যখন পরিষেবাটি প্রাথমিকভাবে তৈরি করা হয় তখন সিস্টেমটি এক-কালীন সেটআপ পদ্ধতি সম্পাদন করার জন্য এই পদ্ধতিটি ব্যবহার করে (এর আগে এটি হয় onStartCommand() বা onBind() )। যদি পরিষেবাটি ইতিমধ্যেই চলমান থাকে তবে এই পদ্ধতিটি বলা হয় না।
onDestroy()
যখন পরিষেবাটি আর ব্যবহার করা হয় না এবং ধ্বংস করা হয় তখন সিস্টেমটি এই পদ্ধতিটি চালু করে৷ থ্রেড, নিবন্ধিত শ্রোতা বা রিসিভারের মতো কোনো সংস্থান পরিষ্কার করার জন্য আপনার পরিষেবার এটি বাস্তবায়ন করা উচিত। এটিই শেষ কল যা পরিষেবাটি গ্রহণ করে।

যদি একটি কম্পোনেন্ট startService() কল করে পরিষেবা শুরু করে (যার ফলে onStartCommand() এ কল আসে), পরিষেবাটি চলতে থাকে যতক্ষণ না এটি stopSelf() দিয়ে থামে বা অন্য কোনও উপাদান stopService() কল করে এটি বন্ধ করে দেয়।

যদি একটি কম্পোনেন্ট bindService() পরিষেবা তৈরি করতে কল করে এবং onStartCommand() কল না করা হয়, তাহলে পরিষেবাটি ততক্ষণ চলবে যতক্ষণ না কম্পোনেন্ট এটির সাথে আবদ্ধ থাকে। পরিষেবাটি তার সমস্ত ক্লায়েন্টদের থেকে আনবাউন্ড হওয়ার পরে, সিস্টেম এটিকে ধ্বংস করে দেয়।

মেমরি কম হলেই অ্যান্ড্রয়েড সিস্টেম একটি পরিষেবা বন্ধ করে এবং ব্যবহারকারীর ফোকাস আছে এমন কার্যকলাপের জন্য এটিকে অবশ্যই সিস্টেম সংস্থান পুনরুদ্ধার করতে হবে। যদি পরিষেবাটি এমন একটি ক্রিয়াকলাপের সাথে আবদ্ধ হয় যেখানে ব্যবহারকারীর ফোকাস রয়েছে, তবে এটি নিহত হওয়ার সম্ভাবনা কম; যদি পরিষেবাটি অগ্রভাগে চালানোর জন্য ঘোষণা করা হয় তবে এটি খুব কমই মারা যায়। যদি পরিষেবাটি শুরু করা হয় এবং দীর্ঘমেয়াদী চলমান থাকে, তবে সিস্টেমটি সময়ের সাথে সাথে পটভূমির কাজের তালিকায় তার অবস্থানকে কমিয়ে দেয় এবং পরিষেবাটি হত্যার জন্য অত্যন্ত সংবেদনশীল হয়ে ওঠে-যদি আপনার পরিষেবাটি শুরু করা হয়, তাহলে আপনাকে অবশ্যই এটি ডিজাইন করতে হবে যাতে এটি পুনরায় চালু করা হয়। সিস্টেম যদি সিস্টেমটি আপনার পরিষেবাটিকে মেরে ফেলে, তবে সংস্থানগুলি উপলব্ধ হওয়ার সাথে সাথে এটি পুনরায় চালু করে, তবে আপনি onStartCommand() থেকে যে মানটি ফেরত তাও এটি নির্ভর করে। সিস্টেম কখন একটি পরিষেবা ধ্বংস করতে পারে সে সম্পর্কে আরও তথ্যের জন্য, প্রসেস এবং থ্রেডিং নথি দেখুন।

নিম্নলিখিত বিভাগগুলিতে, আপনি কীভাবে startService() এবং bindService() পরিষেবা পদ্ধতি তৈরি করতে পারেন, সেইসাথে অন্যান্য অ্যাপ্লিকেশন উপাদানগুলি থেকে কীভাবে ব্যবহার করবেন তা দেখতে পাবেন।

ম্যানিফেস্টে একটি পরিষেবা ঘোষণা করা

আপনাকে অবশ্যই আপনার অ্যাপ্লিকেশনের ম্যানিফেস্ট ফাইলে সমস্ত পরিষেবা ঘোষণা করতে হবে, ঠিক যেমন আপনি কার্যকলাপ এবং অন্যান্য উপাদানগুলির জন্য করেন৷

আপনার পরিষেবা ঘোষণা করতে, <application> উপাদানের একটি শিশু হিসাবে একটি <service> উপাদান যোগ করুন। এখানে একটি উদাহরণ:

<manifest ... >
  ...
  <application ... >
      <service android:name=".ExampleService" />
      ...
  </application>
</manifest>

ম্যানিফেস্টে আপনার পরিষেবা ঘোষণা করার বিষয়ে আরও তথ্যের জন্য <service> উপাদান রেফারেন্স দেখুন।

অন্যান্য বৈশিষ্ট্য রয়েছে যা আপনি <service> এলিমেন্টে অন্তর্ভুক্ত করতে পারেন বৈশিষ্ট্যগুলি সংজ্ঞায়িত করতে যেমন পরিষেবাটি শুরু করার জন্য প্রয়োজনীয় অনুমতি এবং পরিষেবাটি চালানো উচিত এমন প্রক্রিয়া। android:name অ্যাট্রিবিউট হল একমাত্র প্রয়োজনীয় অ্যাট্রিবিউট—এটি পরিষেবার ক্লাসের নাম নির্দিষ্ট করে। আপনি আপনার আবেদন প্রকাশ করার পরে, পরিষেবাটি শুরু বা আবদ্ধ করার সুস্পষ্ট অভিপ্রায়ের উপর নির্ভরতার কারণে কোড ভাঙার ঝুঁকি এড়াতে এই নামটি অপরিবর্তিত রাখুন (ব্লগ পোস্টটি পড়ুন, থিংস যা পরিবর্তন করা যায় না )।

সতর্কতা : আপনার অ্যাপটি সুরক্ষিত তা নিশ্চিত করতে, একটি Service শুরু করার সময় সর্বদা একটি স্পষ্ট অভিপ্রায় ব্যবহার করুন এবং আপনার পরিষেবাগুলির জন্য অভিপ্রায় ফিল্টার ঘোষণা করবেন না। একটি পরিষেবা শুরু করার জন্য একটি অন্তর্নিহিত উদ্দেশ্য ব্যবহার করা একটি নিরাপত্তা বিপত্তি কারণ আপনি অভিপ্রায়ে সাড়া দেয় এমন পরিষেবা সম্পর্কে নিশ্চিত হতে পারবেন না এবং ব্যবহারকারী দেখতে পাচ্ছেন না কোন পরিষেবাটি শুরু হয়৷ অ্যান্ড্রয়েড 5.0 (API স্তর 21) দিয়ে শুরু করে, আপনি যদি একটি অন্তর্নিহিত অভিপ্রায়ে bindService() কল করেন তবে সিস্টেমটি একটি ব্যতিক্রম ছুঁড়ে দেয়।

আপনি নিশ্চিত করতে পারেন যে আপনার পরিষেবাটি শুধুমাত্র আপনার অ্যাপে উপলব্ধ রয়েছে android:exported অ্যাট্রিবিউটটি অন্তর্ভুক্ত করে এবং এটিকে false সেট করে৷ এটি অন্য অ্যাপগুলিকে আপনার পরিষেবা শুরু করা থেকে কার্যকরভাবে বন্ধ করে দেয়, এমনকি একটি স্পষ্ট উদ্দেশ্য ব্যবহার করার সময়ও।

দ্রষ্টব্য : ব্যবহারকারীরা তাদের ডিভাইসে কোন পরিষেবাগুলি চলছে তা দেখতে পারেন৷ যদি তারা এমন একটি পরিষেবা দেখতে পায় যা তারা চিনতে পারে না বা বিশ্বাস করে না, তারা পরিষেবাটি বন্ধ করতে পারে৷ ব্যবহারকারীদের দ্বারা দুর্ঘটনাক্রমে আপনার পরিষেবা বন্ধ না করার জন্য, আপনাকে আপনার অ্যাপ ম্যানিফেস্টে <service> উপাদানটিতে android:description বৈশিষ্ট্য যোগ করতে হবে। বিবরণে, পরিষেবাটি কী করে এবং এটি কী সুবিধা প্রদান করে তা ব্যাখ্যা করে একটি ছোট বাক্য প্রদান করুন।

একটি শুরু পরিষেবা তৈরি করা হচ্ছে

একটি স্টার্ট সার্ভিস হল এমন একটি যা অন্য একটি উপাদান startService() কল করার মাধ্যমে শুরু হয়, যার ফলে পরিষেবাটির onStartCommand() পদ্ধতিতে কল করা হয়।

যখন একটি পরিষেবা শুরু করা হয়, তখন এটির একটি জীবনচক্র থাকে যা এটি যে উপাদানটি শুরু করেছিল তার থেকে স্বতন্ত্র। পরিষেবাটি অনির্দিষ্টকালের জন্য ব্যাকগ্রাউন্ডে চলতে পারে, এমনকি যদি এটি শুরু করা উপাদানটি ধ্বংস হয়ে যায়। যেমন, পরিষেবাটি stopSelf() কল করে কাজ শেষ হয়ে গেলে, অথবা অন্য কোনো উপাদান stopService() কল করে এটি বন্ধ করতে পারে।

একটি অ্যাপ্লিকেশান উপাদান যেমন একটি কার্যকলাপ startService() কল করে এবং পরিষেবাটি নির্দিষ্ট করে এবং পরিষেবা ব্যবহারের জন্য যে কোনও ডেটা অন্তর্ভুক্ত করে এমন একটি Intent পাস করে পরিষেবা শুরু করতে পারে। পরিষেবাটি onStartCommand() পদ্ধতিতে এই Intent গ্রহণ করে।

উদাহরণস্বরূপ, ধরুন একটি কার্যকলাপের জন্য একটি অনলাইন ডাটাবেসে কিছু ডেটা সংরক্ষণ করতে হবে। ক্রিয়াকলাপটি একটি সহচর পরিষেবা শুরু করতে পারে এবং startService() এ একটি অভিপ্রায় পাস করে সংরক্ষণ করার জন্য ডেটা সরবরাহ করতে পারে৷ পরিষেবাটি onStartCommand() এ অভিপ্রায় গ্রহণ করে, ইন্টারনেটের সাথে সংযোগ স্থাপন করে এবং ডাটাবেস লেনদেন সম্পাদন করে। লেনদেন সম্পূর্ণ হলে, পরিষেবাটি নিজেই বন্ধ হয়ে যায় এবং ধ্বংস হয়ে যায়।

সতর্কতা: একটি পরিষেবা একই প্রক্রিয়ায় চলে যে অ্যাপ্লিকেশনটিতে এটি ঘোষণা করা হয় এবং ডিফল্টরূপে সেই অ্যাপ্লিকেশনটির মূল থ্রেডে। ব্যবহারকারী একই অ্যাপ্লিকেশন থেকে একটি কার্যকলাপের সাথে ইন্টারঅ্যাক্ট করার সময় আপনার পরিষেবা যদি নিবিড় বা ব্লকিং ক্রিয়াকলাপ সম্পাদন করে, পরিষেবাটি কার্যকলাপের কার্যকারিতাকে ধীর করে দেয়। অ্যাপ্লিকেশন কর্মক্ষমতা প্রভাবিত এড়াতে, পরিষেবার ভিতরে একটি নতুন থ্রেড শুরু করুন।

Service ক্লাস হল সমস্ত পরিষেবার জন্য বেস ক্লাস। যখন আপনি এই ক্লাসটি প্রসারিত করেন, তখন একটি নতুন থ্রেড তৈরি করা গুরুত্বপূর্ণ যেখানে পরিষেবাটি তার সমস্ত কাজ সম্পূর্ণ করতে পারে; পরিষেবাটি ডিফল্টরূপে আপনার অ্যাপ্লিকেশনের প্রধান থ্রেড ব্যবহার করে, যা আপনার অ্যাপ্লিকেশনটি চলমান যে কোনো কার্যকলাপের কর্মক্ষমতাকে ধীর করে দিতে পারে।

অ্যান্ড্রয়েড ফ্রেমওয়ার্ক Service IntentService সাবক্লাসও সরবরাহ করে যা একটি ওয়ার্কার থ্রেড ব্যবহার করে শুরুর সমস্ত অনুরোধগুলিকে একবারে একটি করে পরিচালনা করে। নতুন অ্যাপগুলির জন্য এই ক্লাসটি ব্যবহার করা বাঞ্ছনীয় নয় কারণ এটি Android 8 Oreo থেকে শুরু করে ভালভাবে কাজ করবে না, কারণ ব্যাকগ্রাউন্ড এক্সিকিউশন সীমা প্রবর্তন করা হয়েছে৷ তাছাড়া, অ্যান্ড্রয়েড 11 থেকে শুরু করে এটিকে অবমূল্যায়ন করা হয়েছে। আপনি IntentService এর প্রতিস্থাপন হিসাবে JobIntentService ব্যবহার করতে পারেন যা Android এর নতুন সংস্করণগুলির সাথে সামঞ্জস্যপূর্ণ।

নিম্নলিখিত বিভাগগুলি বর্ণনা করে যে আপনি কীভাবে আপনার নিজস্ব কাস্টম পরিষেবা বাস্তবায়ন করতে পারেন, তবে বেশিরভাগ ব্যবহারের ক্ষেত্রে আপনার পরিবর্তে WorkManager ব্যবহার করার বিষয়ে দৃঢ়ভাবে বিবেচনা করা উচিত। আপনার প্রয়োজনের সাথে মানানসই কোনো সমাধান আছে কিনা তা দেখতে Android-এ ব্যাকগ্রাউন্ড প্রসেসিংয়ের গাইডের সাথে পরামর্শ করুন।

সার্ভিস ক্লাস প্রসারিত করা হচ্ছে

আপনি প্রতিটি আগত অভিপ্রায় পরিচালনা করতে Service ক্লাস প্রসারিত করতে পারেন। এখানে একটি মৌলিক বাস্তবায়ন দেখতে কেমন হতে পারে:

কোটলিন

class HelloService : Service() {

    private var serviceLooper: Looper? = null
    private var serviceHandler: ServiceHandler? = null

    // Handler that receives messages from the thread
    private inner class ServiceHandler(looper: Looper) : Handler(looper) {

        override fun handleMessage(msg: Message) {
            // Normally we would do some work here, like download a file.
            // For our sample, we just sleep for 5 seconds.
            try {
                Thread.sleep(5000)
            } catch (e: InterruptedException) {
                // Restore interrupt status.
                Thread.currentThread().interrupt()
            }

            // Stop the service using the startId, so that we don't stop
            // the service in the middle of handling another job
            stopSelf(msg.arg1)
        }
    }

    override fun onCreate() {
        // Start up the thread running the service.  Note that we create a
        // separate thread because the service normally runs in the process's
        // main thread, which we don't want to block.  We also make it
        // background priority so CPU-intensive work will not disrupt our UI.
        HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND).apply {
            start()

            // Get the HandlerThread's Looper and use it for our Handler
            serviceLooper = looper
            serviceHandler = ServiceHandler(looper)
        }
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show()

        // For each start request, send a message to start a job and deliver the
        // start ID so we know which request we're stopping when we finish the job
        serviceHandler?.obtainMessage()?.also { msg ->
            msg.arg1 = startId
            serviceHandler?.sendMessage(msg)
        }

        // If we get killed, after returning from here, restart
        return START_STICKY
    }

    override fun onBind(intent: Intent): IBinder? {
        // We don't provide binding, so return null
        return null
    }

    override fun onDestroy() {
        Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show()
    }
}

জাভা

public class HelloService extends Service {
  private Looper serviceLooper;
  private ServiceHandler serviceHandler;

  // Handler that receives messages from the thread
  private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
          super(looper);
      }
      @Override
      public void handleMessage(Message msg) {
          // Normally we would do some work here, like download a file.
          // For our sample, we just sleep for 5 seconds.
          try {
              Thread.sleep(5000);
          } catch (InterruptedException e) {
              // Restore interrupt status.
              Thread.currentThread().interrupt();
          }
          // Stop the service using the startId, so that we don't stop
          // the service in the middle of handling another job
          stopSelf(msg.arg1);
      }
  }

  @Override
  public void onCreate() {
    // Start up the thread running the service. Note that we create a
    // separate thread because the service normally runs in the process's
    // main thread, which we don't want to block. We also make it
    // background priority so CPU-intensive work doesn't disrupt our UI.
    HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
    thread.start();

    // Get the HandlerThread's Looper and use it for our Handler
    serviceLooper = thread.getLooper();
    serviceHandler = new ServiceHandler(serviceLooper);
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

      // For each start request, send a message to start a job and deliver the
      // start ID so we know which request we're stopping when we finish the job
      Message msg = serviceHandler.obtainMessage();
      msg.arg1 = startId;
      serviceHandler.sendMessage(msg);

      // If we get killed, after returning from here, restart
      return START_STICKY;
  }

  @Override
  public IBinder onBind(Intent intent) {
      // We don't provide binding, so return null
      return null;
  }

  @Override
  public void onDestroy() {
    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
  }
}

উদাহরণ কোডটি onStartCommand() এ সমস্ত ইনকামিং কল পরিচালনা করে এবং একটি ব্যাকগ্রাউন্ড থ্রেডে চলমান Handler কাছে কাজটি পোস্ট করে। এটি একটি IntentService এর মতো কাজ করে এবং একের পর এক ধারাবাহিকভাবে সমস্ত অনুরোধ প্রক্রিয়া করে। আপনি একটি থ্রেড পুলে কাজ চালানোর জন্য কোড পরিবর্তন করতে পারেন, উদাহরণস্বরূপ, যদি আপনি একই সাথে একাধিক অনুরোধ চালাতে চান।

লক্ষ্য করুন যে onStartCommand() পদ্ধতি অবশ্যই একটি পূর্ণসংখ্যা প্রদান করবে। পূর্ণসংখ্যা হল এমন একটি মান যা বর্ণনা করে যে সিস্টেমটি কীভাবে এটিকে মেরে ফেললে পরিষেবাটি চালিয়ে যেতে হবে। onStartCommand() থেকে রিটার্ন মান নিম্নলিখিত ধ্রুবকগুলির মধ্যে একটি হতে হবে:

START_NOT_STICKY
onStartCommand() রিটার্ন করার পরে যদি সিস্টেমটি পরিষেবাটিকে মেরে ফেলে, তবে পরিষেবাটি পুনরায় তৈরি করবেন না যদি না বিতরণ করার জন্য মুলতুবি থাকা উদ্দেশ্য থাকে। প্রয়োজন না হলে আপনার পরিষেবা চালানো এড়ানোর জন্য এটি সবচেয়ে নিরাপদ বিকল্প এবং যখন আপনার আবেদনটি কোনো অসমাপ্ত কাজ পুনরায় চালু করতে পারে।
START_STICKY
onStartCommand() ফিরে আসার পরে যদি সিস্টেমটি পরিষেবাটিকে মেরে ফেলে, তাহলে পরিষেবাটি পুনরায় তৈরি করুন এবং onStartCommand() কল করুন, কিন্তু শেষ উদ্দেশ্যটি পুনরায় বিতরণ করবেন না । পরিবর্তে, সিস্টেমটি একটি শূন্য অভিপ্রায় সহ onStartCommand() কল করে যদি না পরিষেবাটি শুরু করার জন্য মুলতুবি থাকা উদ্দেশ্য থাকে। সেই ক্ষেত্রে, সেই অভিপ্রায়গুলি বিতরণ করা হয়। এটি মিডিয়া প্লেয়ারদের (বা অনুরূপ পরিষেবা) জন্য উপযুক্ত যারা কমান্ড কার্যকর করছে না কিন্তু অনির্দিষ্টকালের জন্য চলছে এবং চাকরির জন্য অপেক্ষা করছে।
START_REDELIVER_INTENT
onStartCommand() রিটার্ন করার পরে সিস্টেমটি পরিষেবাটিকে মেরে ফেললে, পরিষেবাটি পুনরায় তৈরি করুন এবং পরিষেবাটিতে বিতরণ করা শেষ অভিপ্রায় দিয়ে onStartCommand() কল করুন৷ কোনো মুলতুবি অভিপ্রায় পালাক্রমে বিতরণ করা হয়. এটি এমন পরিষেবাগুলির জন্য উপযুক্ত যা সক্রিয়ভাবে একটি কাজ সম্পাদন করছে যা অবিলম্বে পুনরায় শুরু করা উচিত, যেমন একটি ফাইল ডাউনলোড করা।

এই রিটার্ন মান সম্পর্কে আরো বিস্তারিত জানার জন্য, প্রতিটি ধ্রুবকের জন্য লিঙ্ক করা রেফারেন্স ডকুমেন্টেশন দেখুন।

একটি পরিষেবা শুরু করা হচ্ছে

আপনি startService() বা startForegroundService() এ একটি Intent পাস করে একটি কার্যকলাপ বা অন্য অ্যাপ্লিকেশন উপাদান থেকে একটি পরিষেবা শুরু করতে পারেন। অ্যান্ড্রয়েড সিস্টেম পরিষেবাটির onStartCommand() পদ্ধতিকে কল করে এবং এটিকে Intent পাস করে, যা কোন পরিষেবাটি শুরু করতে হবে তা নির্দিষ্ট করে৷

দ্রষ্টব্য : যদি আপনার অ্যাপটি API লেভেল 26 বা তার বেশি লক্ষ্য করে, তাহলে অ্যাপটি ফোরগ্রাউন্ডে না থাকলে সিস্টেম ব্যাকগ্রাউন্ড পরিষেবা ব্যবহার বা তৈরি করার উপর বিধিনিষেধ আরোপ করে। যদি একটি অ্যাপকে একটি ফোরগ্রাউন্ড পরিষেবা তৈরি করতে হয়, অ্যাপটিকে startForegroundService() কল করা উচিত। এই পদ্ধতিটি একটি ব্যাকগ্রাউন্ড পরিষেবা তৈরি করে, কিন্তু পদ্ধতিটি সিস্টেমকে সংকেত দেয় যে পরিষেবাটি নিজেকে অগ্রভাগে প্রচার করবে। পরিষেবাটি তৈরি হয়ে গেলে, পরিষেবাটিকে অবশ্যই পাঁচ সেকেন্ডের মধ্যে তার startForeground() পদ্ধতিতে কল করতে হবে।

উদাহরণস্বরূপ, একটি কার্যকলাপ পূর্ববর্তী বিভাগে উদাহরণ পরিষেবা শুরু করতে পারে ( HelloService ) startService() এর সাথে একটি স্পষ্ট উদ্দেশ্য ব্যবহার করে, যেমনটি এখানে দেখানো হয়েছে:

কোটলিন

startService(Intent(this, HelloService::class.java))

জাভা

startService(new Intent(this, HelloService.class));

startService() পদ্ধতি অবিলম্বে ফিরে আসে, এবং Android সিস্টেম পরিষেবাটির onStartCommand() পদ্ধতিতে কল করে। পরিষেবাটি ইতিমধ্যে চালু না হলে, সিস্টেমটি প্রথমে কল করে onCreate() , এবং তারপর এটি কল করে onStartCommand()

যদি পরিষেবাটি বাইন্ডিং প্রদান না করে, startService() এর মাধ্যমে যে অভিপ্রায় প্রদান করা হয় তা হল অ্যাপ্লিকেশন উপাদান এবং পরিষেবার মধ্যে যোগাযোগের একমাত্র মোড। যাইহোক, যদি আপনি চান যে পরিষেবাটি একটি ফলাফল ফেরত পাঠায়, যে ক্লায়েন্ট পরিষেবাটি শুরু করে সে একটি সম্প্রচারের জন্য একটি PendingIntent তৈরি করতে পারে ( getBroadcast() সহ ) এবং পরিষেবাটি শুরু করার Intent পরিষেবাতে সরবরাহ করতে পারে৷ পরিষেবাটি তারপর ফলাফল প্রদান করতে সম্প্রচার ব্যবহার করতে পারে।

পরিষেবা শুরু করার একাধিক অনুরোধের ফলে পরিষেবার onStartCommand() -এ একাধিক সংশ্লিষ্ট কল আসে৷ যাইহোক, পরিষেবাটি বন্ধ করার জন্য শুধুমাত্র একটি অনুরোধ ( stopSelf() বা stopService() সহ এটি বন্ধ করার জন্য প্রয়োজন৷

একটি পরিষেবা বন্ধ করা

একটি শুরু করা পরিষেবাকে অবশ্যই তার নিজের জীবনচক্র পরিচালনা করতে হবে। অর্থাৎ, সিস্টেমটি পরিষেবাটিকে বন্ধ বা ধ্বংস করে না যদি না এটিকে সিস্টেম মেমরি পুনরুদ্ধার করতে হয় এবং onStartCommand() ফিরে আসার পরে পরিষেবাটি চলতে থাকে। পরিষেবাটি অবশ্যই stopSelf() কল করে নিজেকে থামাতে হবে, অথবা অন্য একটি উপাদান stopService() কল করে এটি বন্ধ করতে পারে।

একবার stopSelf() বা stopService() দিয়ে থামতে অনুরোধ করা হলে, সিস্টেম যত তাড়াতাড়ি সম্ভব পরিষেবাটি ধ্বংস করে দেয়।

যদি আপনার পরিষেবা একযোগে onStartCommand() এর একাধিক অনুরোধ পরিচালনা করে, তাহলে আপনার একটি স্টার্ট রিকোয়েস্ট প্রসেস করা হয়ে গেলে আপনার পরিষেবাটি বন্ধ করা উচিত নয়, কারণ আপনি হয়ত একটি নতুন স্টার্ট রিকোয়েস্ট পেয়েছেন (প্রথম অনুরোধের শেষে থামলে তা বন্ধ হয়ে যাবে। দ্বিতীয়টি)। এই সমস্যাটি এড়াতে, আপনি stopSelf(int) ব্যবহার করতে পারেন যাতে পরিষেবাটি বন্ধ করার আপনার অনুরোধ সর্বদা সাম্প্রতিক শুরুর অনুরোধের উপর ভিত্তি করে করা হয়। অর্থাৎ, আপনি যখন stopSelf(int) কল করেন, তখন আপনি স্টার্ট রিকোয়েস্টের আইডি পাস করেন (যে startId onStartCommand() এ বিতরণ করা হয়) যার সাথে আপনার স্টপ রিকোয়েস্টের মিল রয়েছে। তারপর, যদি আপনি stopSelf(int) কল করতে সক্ষম হওয়ার আগে পরিষেবাটি একটি নতুন শুরুর অনুরোধ পায়, তাহলে আইডি মেলে না এবং পরিষেবাটি বন্ধ হয় না।

সতর্কতা: সিস্টেম রিসোর্স নষ্ট করা এবং ব্যাটারি পাওয়ার খরচ এড়াতে, নিশ্চিত করুন যে আপনার অ্যাপ্লিকেশানটি কাজ করা হয়ে গেলে তার পরিষেবাগুলি বন্ধ করে দেয়৷ প্রয়োজনে, অন্যান্য উপাদানগুলি stopService() কল করে পরিষেবাটি বন্ধ করতে পারে। এমনকি যদি আপনি পরিষেবার জন্য বাইন্ডিং সক্ষম করেন, তবে আপনাকে অবশ্যই পরিষেবাটি বন্ধ করতে হবে যদি এটি কখনও onStartCommand() এ কল পায়।

একটি পরিষেবার জীবনচক্র সম্পর্কে আরও তথ্যের জন্য, একটি পরিষেবার জীবনচক্র পরিচালনা সম্পর্কে নীচের বিভাগটি দেখুন৷

একটি আবদ্ধ পরিষেবা তৈরি করা

একটি আবদ্ধ পরিষেবা হল একটি দীর্ঘস্থায়ী সংযোগ তৈরি করতে bindService() কল করে অ্যাপ্লিকেশন উপাদানগুলিকে এটির সাথে আবদ্ধ হতে দেয়৷ এটি সাধারণত startService() কল করে উপাদানগুলিকে এটি শুরু করার অনুমতি দেয় না।

আপনি যখন আপনার অ্যাপ্লিকেশনের কার্যকলাপ এবং অন্যান্য উপাদান থেকে পরিষেবার সাথে ইন্টারঅ্যাক্ট করতে চান বা ইন্টারপ্রসেস কমিউনিকেশন (IPC) এর মাধ্যমে আপনার অ্যাপ্লিকেশনের কিছু কার্যকারিতা অন্যান্য অ্যাপ্লিকেশনগুলিতে প্রকাশ করতে চান তখন একটি আবদ্ধ পরিষেবা তৈরি করুন৷

একটি আবদ্ধ পরিষেবা তৈরি করতে, পরিষেবার সাথে যোগাযোগের জন্য ইন্টারফেস সংজ্ঞায়িত করে এমন একটি IBinder ফেরাতে onBind() কলব্যাক পদ্ধতি প্রয়োগ করুন। অন্যান্য অ্যাপ্লিকেশন উপাদানগুলি তখন ইন্টারফেস পুনরুদ্ধার করতে bindService() কল করতে পারে এবং পরিষেবাটিতে কল করার পদ্ধতি শুরু করতে পারে। পরিষেবাটি শুধুমাত্র অ্যাপ্লিকেশন উপাদানটিকে পরিবেশন করার জন্য বেঁচে থাকে যা এটির সাথে আবদ্ধ থাকে, তাই যখন পরিষেবার সাথে আবদ্ধ কোন উপাদান থাকে না, তখন সিস্টেমটি এটিকে ধ্বংস করে দেয়। onStartCommand() এর মাধ্যমে পরিষেবাটি শুরু করার সময় আপনাকে যেভাবে বাধ্যতামূলক পরিষেবা বন্ধ করতে হবে সেভাবে আপনাকে বন্ধ করতে হবে না

একটি আবদ্ধ পরিষেবা তৈরি করতে, আপনাকে অবশ্যই ইন্টারফেসটি সংজ্ঞায়িত করতে হবে যা নির্দিষ্ট করে যে কীভাবে একজন ক্লায়েন্ট পরিষেবার সাথে যোগাযোগ করতে পারে। পরিষেবা এবং একটি ক্লায়েন্টের মধ্যে এই ইন্টারফেসটি অবশ্যই IBinder এর একটি বাস্তবায়ন হতে হবে এবং আপনার পরিষেবাটি অবশ্যই onBind() কলব্যাক পদ্ধতি থেকে ফিরে আসবে৷ ক্লায়েন্ট IBinder প্রাপ্ত করার পরে, এটি সেই ইন্টারফেসের মাধ্যমে পরিষেবার সাথে যোগাযোগ শুরু করতে পারে।

একাধিক ক্লায়েন্ট একই সাথে পরিষেবার সাথে আবদ্ধ হতে পারে। যখন একটি ক্লায়েন্ট পরিষেবার সাথে ইন্টারঅ্যাক্ট করা হয়, তখন এটি unbindService() কে আনবাইন্ড করতে বলে। যখন কোনও ক্লায়েন্ট পরিষেবার সাথে আবদ্ধ থাকে না, সিস্টেমটি পরিষেবাটি ধ্বংস করে দেয়।

একটি আবদ্ধ পরিষেবা বাস্তবায়নের একাধিক উপায় রয়েছে এবং একটি শুরু করা পরিষেবার চেয়ে বাস্তবায়ন আরও জটিল৷ এই কারণে, আবদ্ধ পরিষেবা আলোচনা আবদ্ধ পরিষেবা সম্পর্কে একটি পৃথক নথিতে উপস্থিত হয়৷

ব্যবহারকারীকে বিজ্ঞপ্তি পাঠানো হচ্ছে

যখন একটি পরিষেবা চলছে, তখন এটি স্ন্যাকবার বিজ্ঞপ্তি বা স্ট্যাটাস বার বিজ্ঞপ্তিগুলি ব্যবহার করে ইভেন্টগুলির ব্যবহারকারীকে অবহিত করতে পারে৷

একটি স্ন্যাকবার বিজ্ঞপ্তি হল একটি বার্তা যা অদৃশ্য হওয়ার আগে মাত্র এক মুহুর্তের জন্য বর্তমান উইন্ডোর পৃষ্ঠে উপস্থিত হয়। একটি স্ট্যাটাস বার বিজ্ঞপ্তি একটি বার্তা সহ স্ট্যাটাস বারে একটি আইকন প্রদান করে, যা ব্যবহারকারী একটি পদক্ষেপ নেওয়ার জন্য নির্বাচন করতে পারেন (যেমন একটি কার্যকলাপ শুরু করুন)।

সাধারণত, একটি স্ট্যাটাস বার নোটিফিকেশন হল ব্যাকগ্রাউন্ডের কাজ যেমন একটি ফাইল ডাউনলোড শেষ হলে ব্যবহার করার সর্বোত্তম কৌশল, এবং ব্যবহারকারী এখন এটিতে কাজ করতে পারে। যখন ব্যবহারকারী প্রসারিত দৃশ্য থেকে বিজ্ঞপ্তিটি নির্বাচন করেন, তখন বিজ্ঞপ্তিটি একটি কার্যকলাপ শুরু করতে পারে (যেমন ডাউনলোড করা ফাইলটি প্রদর্শন করা)।

একটি পরিষেবার জীবনচক্র পরিচালনা

একটি পরিষেবার জীবনচক্র একটি কার্যকলাপের তুলনায় অনেক সহজ। যাইহোক, এটি আরও গুরুত্বপূর্ণ যে আপনি কীভাবে আপনার পরিষেবা তৈরি এবং ধ্বংস করা হয় তার প্রতি গভীর মনোযোগ দিন কারণ ব্যবহারকারীকে সচেতন না করেই একটি পরিষেবা ব্যাকগ্রাউন্ডে চলতে পারে।

পরিষেবা জীবনচক্র - কখন এটি তৈরি করা হয়েছে থেকে কখন এটি ধ্বংস হয়ে গেছে - এই দুটি পথের যেকোনো একটি অনুসরণ করতে পারে:

  • একটি শুরু করা পরিষেবা

    পরিষেবাটি তৈরি করা হয় যখন অন্য একটি উপাদান startService() কল করে। পরিষেবাটি তারপর অনির্দিষ্টকালের জন্য চলে এবং stopSelf() কল করে নিজেকে থামাতে হবে। অন্য একটি উপাদানও stopService() কল করে পরিষেবাটি বন্ধ করতে পারে। পরিষেবাটি বন্ধ হয়ে গেলে, সিস্টেমটি এটিকে ধ্বংস করে দেয়।

  • একটি আবদ্ধ সেবা

    পরিষেবাটি তৈরি হয় যখন অন্য একটি উপাদান (একটি ক্লায়েন্ট) bindService() কল করে। ক্লায়েন্ট তারপর একটি IBinder ইন্টারফেসের মাধ্যমে পরিষেবার সাথে যোগাযোগ করে। ক্লায়েন্ট unbindService() কল করে সংযোগটি বন্ধ করতে পারে। একাধিক ক্লায়েন্ট একই পরিষেবার সাথে আবদ্ধ হতে পারে এবং যখন তাদের সকলকে আবদ্ধ করে, সিস্টেমটি পরিষেবাটি ধ্বংস করে দেয়। পরিষেবাটি নিজেকে বন্ধ করার দরকার নেই

এই দুটি পথ সম্পূর্ণ আলাদা নয়। আপনি একটি পরিষেবার সাথে আবদ্ধ করতে পারেন যা ইতিমধ্যে startService() দিয়ে শুরু হয়েছে। উদাহরণস্বরূপ, আপনি একটি পটভূমি সঙ্গীত পরিষেবা শুরু করতে পারেন startService() এ কল করে একটি Intent যা বাজানোর জন্য সঙ্গীত সনাক্ত করে৷ পরে, সম্ভবত যখন ব্যবহারকারী প্লেয়ারের উপর কিছু নিয়ন্ত্রণ করতে চান বা বর্তমান গান সম্পর্কে তথ্য পেতে চান, bindService() কল করে একটি কার্যকলাপ পরিষেবার সাথে আবদ্ধ হতে পারে। এই ধরনের ক্ষেত্রে, stopService() বা stopSelf() প্রকৃতপক্ষে পরিষেবা বন্ধ করে না যতক্ষণ না সমস্ত ক্লায়েন্ট আবদ্ধ না করে।

জীবনচক্র কলব্যাক বাস্তবায়ন করা

একটি ক্রিয়াকলাপের মতো, একটি পরিষেবাতে লাইফসাইকেল কলব্যাক পদ্ধতি রয়েছে যা আপনি পরিষেবার অবস্থার পরিবর্তনগুলি নিরীক্ষণ করতে এবং উপযুক্ত সময়ে কাজ সম্পাদন করতে প্রয়োগ করতে পারেন৷ নিম্নলিখিত কঙ্কাল পরিষেবা প্রতিটি জীবনচক্র পদ্ধতি প্রদর্শন করে:

কোটলিন

class ExampleService : Service() {
    private var startMode: Int = 0             // indicates how to behave if the service is killed
    private var binder: IBinder? = null        // interface for clients that bind
    private var allowRebind: Boolean = false   // indicates whether onRebind should be used

    override fun onCreate() {
        // The service is being created
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // The service is starting, due to a call to startService()
        return startMode
    }

    override fun onBind(intent: Intent): IBinder? {
        // A client is binding to the service with bindService()
        return binder
    }

    override fun onUnbind(intent: Intent): Boolean {
        // All clients have unbound with unbindService()
        return allowRebind
    }

    override fun onRebind(intent: Intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }

    override fun onDestroy() {
        // The service is no longer used and is being destroyed
    }
}

জাভা

public class ExampleService extends Service {
    int startMode;       // indicates how to behave if the service is killed
    IBinder binder;      // interface for clients that bind
    boolean allowRebind; // indicates whether onRebind should be used

    @Override
    public void onCreate() {
        // The service is being created
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // The service is starting, due to a call to startService()
        return startMode;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // A client is binding to the service with bindService()
        return binder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        // All clients have unbound with unbindService()
        return allowRebind;
    }
    @Override
    public void onRebind(Intent intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }
    @Override
    public void onDestroy() {
        // The service is no longer used and is being destroyed
    }
}

দ্রষ্টব্য: অ্যাক্টিভিটি লাইফসাইকেল কলব্যাক পদ্ধতির বিপরীতে, আপনাকে এই কলব্যাক পদ্ধতিগুলির সুপারক্লাস বাস্তবায়ন কল করার প্রয়োজন নেই

চিত্র 2. পরিষেবা জীবনচক্র। বাম দিকের চিত্রটি জীবনচক্র দেখায় যখন পরিষেবাটি startService() দিয়ে তৈরি করা হয় এবং ডানদিকের চিত্রটি জীবনচক্র দেখায় যখন পরিষেবাটি bindService() দিয়ে তৈরি করা হয়৷

চিত্র 2 একটি পরিষেবার জন্য সাধারণ কলব্যাক পদ্ধতিগুলিকে চিত্রিত করে৷ যদিও চিত্রটি bindService startService() bindService() দ্বারা তৈরি পরিষেবাগুলিকে আলাদা করে, মনে রাখবেন যে কোনও পরিষেবা, এটি যেভাবেই শুরু হোক না কেন, ক্লায়েন্টদের এটির সাথে আবদ্ধ হওয়ার অনুমতি দিতে পারে৷ একটি পরিষেবা যা প্রাথমিকভাবে onStartCommand() দিয়ে শুরু হয়েছিল (একজন ক্লায়েন্ট কল করে startService() ) এখনও onBind() এ কল পেতে পারে (যখন একজন ক্লায়েন্ট bindService() কল করে)।

এই পদ্ধতিগুলি প্রয়োগ করে, আপনি পরিষেবার জীবনচক্রের এই দুটি নেস্টেড লুপগুলি নিরীক্ষণ করতে পারেন:

  • একটি পরিষেবার সমগ্র জীবনকাল onCreate() কল করার সময় এবং onDestroy() ফেরত আসার সময়ের মধ্যে ঘটে। একটি ক্রিয়াকলাপের মতো, একটি পরিষেবা onCreate() এ তার প্রাথমিক সেটআপ করে এবং onDestroy() এ অবশিষ্ট সমস্ত সংস্থান প্রকাশ করে। উদাহরণস্বরূপ, একটি মিউজিক প্লেব্যাক পরিষেবা থ্রেড তৈরি করতে পারে যেখানে গানটি onCreate() এ বাজানো হয় এবং তারপরে এটি onDestroy() এ থ্রেডটি বন্ধ করতে পারে।

    দ্রষ্টব্য : onCreate() এবং onDestroy() পদ্ধতিগুলি সমস্ত পরিষেবার জন্য বলা হয়, সেগুলি startService() বা bindService() দ্বারা তৈরি করা হোক না কেন।

  • একটি পরিষেবার সক্রিয় জীবনকাল onStartCommand() অথবা onBind() -এ একটি কল দিয়ে শুরু হয়। প্রতিটি পদ্ধতিতে Intent হস্তান্তর করা হয় যা হয় startService() বা bindService() এ পাস করা হয়েছিল।

    যদি পরিষেবাটি শুরু করা হয়, পুরো জীবনকাল শেষ হওয়ার সাথে সাথে সক্রিয় জীবনকাল শেষ হয় ( onStartCommand() ফিরে আসার পরেও পরিষেবাটি সক্রিয় থাকে)। যদি পরিষেবাটি আবদ্ধ থাকে, তাহলে সক্রিয় জীবনকাল শেষ হয়ে যায় যখন onUnbind() ফিরে আসে।

দ্রষ্টব্য: যদিও stopSelf() বা stopService() এ একটি কলের মাধ্যমে একটি শুরু করা পরিষেবা বন্ধ করা হয়, তবে পরিষেবাটির জন্য কোনও স্বতন্ত্র কলব্যাক নেই (কোনও onStop() কলব্যাক নেই)৷ পরিষেবাটি কোনও ক্লায়েন্টের সাথে আবদ্ধ না হলে, পরিষেবাটি বন্ধ হয়ে গেলে সিস্টেম এটিকে ধ্বংস করে দেয়- onDestroy() হল একমাত্র কলব্যাক প্রাপ্ত।

বাইন্ডিং প্রদান করে এমন একটি পরিষেবা তৈরি করার বিষয়ে আরও তথ্যের জন্য, আবদ্ধ পরিষেবার নথি দেখুন, যাতে একটি আবদ্ধ পরিষেবার জীবনচক্র পরিচালনা সম্পর্কিত বিভাগে onRebind() কলব্যাক পদ্ধতি সম্পর্কে আরও তথ্য রয়েছে৷