سرویس ها
سرویس ها (service) کامپوننت هایی هستند که در پشت صحنه برای اجرای عملیات طولانی مدتی که نیاز به تعامل با کاربر ندارند اجرا می شوند. و آنها حتی اگر برنامه پایان یابد کار می کنند. یک سرویس اساسا می تواند دو حالت داشته باشد
State | Description |
Started | یک سرویس حالت started دارد زمانی که یک کامپوننت از برنامه، مانند یک اکتیویتی، آن را با فراخوانی startService() شروع می کند. پس از شروع، سرویس می تواند به طور نامحدود در پس زمینه اجرا شود، حتی اگر کامپوننت آغاز کننده آن نابود شده باشد. |
Bound | حالت bound (محدود) یک سرویس مربوط به زمانی می شود که یک کامپوننت از برنامه با فراخوانی متد bindService() به آن متصل شود. یک سرویس محدود یک واسط کلاینت- سرور ارائه می دهد و به کامپوننت ها اجازه می دهد با سرویس ارتباط برقرار کنند، درخواست های خود را به آن ارسال و نتایج را دریافت کنند، و حتی این کارها را در بین فرایندهایی که دارای ارتباط بین فرایندی هستند (IPC) انجام دهند. |
یک سرویس در چرخه حیات خود یک سری متدهای بازخوردی (callback) دارد که شما می توانید با استفاده از آنها بر تغییر حالت سرویس ها نظارت کنید واقدامات مناسب با هر مرحله را انجام دهید. نمودار زیر در سمت چپ چرخه حیات زمانی که سرویس با ()startService ایجاد شده است را نشان می دهد و نمودار سمت راست چرخه حیات زمانی که سرویس با ()bindService ایجاد شده است را نشان می دهد:
برای ایجاد یک سرویس، یک کلاس جاوا که توسعه دهنده کلاس پایه سرویس است یا یکی از زیرکلاس های آن است را ایجاد کنید. کلاس پایه سرویس متدهای مختلف بازخوردی را تعریف می کند و مهم ترین آنها در جدول زیر آورده شده است. پیاده سازی تمام متدهای بازخوردی لازم نیست. با این حال، درک مفهوم و کارایی هر یک از آنها مهم است و آنهایی را پیاده سازی کنید که اطمینان حاصل شود برنامه شما به روشی کار می کند که کاربران انتظار دارند.
Callback | Description |
onStartCommand() |
سیستم این متد را هنگامی فراخوانی می کند که یک کامپوننت دیگر، مانند یک اکتیویتی، با فراخوانی متد startService() درخواست می کند که سرویس آغاز شود. اگر این متد را پیاده سازی کنید، متوقف کردن سرویس هنگامی که کارش به پایان رسید به عهده شما خواهد بود. این کار با فراخوانی متد stopSelf() یا stopService() قابل انجام است. |
onBind() |
سیستم این متد را هنگامی فراخوانی می کند که کامپوننت دیگری بخواهد با استفاده از متد bindService() به سرویس متصل شود. اگر این متد را پیاده سازی کنید، شما باید بوسیله برگرداندن یک شی IBinder یک رابط برای برقراری ارتباط کلاینت با این سرویس فراهم کنید. شما همیشه باید این متد را پیاده سازی کنید، اما اگر نمی خواهید اجازه اتصال دهید، پس باید مقدار بازگشتی را null تعیین کنید. |
onUnbind() |
سیستم این متد را هنگامی فراخوانی می کند که تمام کلاینت های یک رابط خاص منتشر شده توسط سرویس قطع شده یاشند. |
onRebind() |
پس از اینکه سرویس با استفاده از متد onUnbind(Intent) از قطع شدن تمام کلاینت ها مطلع شد، اگر کلاینت جدیدی به این سرویس متصل شود سیستم این متد را فراخوانی می کند. |
onCreate() |
سیستم این متد را وقتی فراخوانی می کند که سرویس در ابتدا با استفاده از متد ()onStartCommand و یا ()onBind ایجاد شده باشد. فراخوانی این متد تنها یکبار آن هم در زمان راه اندازی برنامه انجام می شود. |
onDestroy() |
سیستم این متد را هنگامی فراخوانی می کند که سرویس مدت زیادی بدون استفاده بماند و در حال از بین رفتن باشد. سرویس شما برای پاک کردن هر منبعی مانند نخ ها، ثبت کننده ها، دریافت کننده ها، و غیره باید این متد را پیاده سازی کند. |
ساختار سرویس زیر، چرخه حیات هر یک از متدها را نشان می دهد:
package com.tutorialspoint; import android.app.Service; import android.os.IBinder; import android.content.Intent; import android.os.Bundle; public class HelloService extends Service { /** indicates how to behave if the service is killed */ int mStartMode; /** interface for clients that bind */ IBinder mBinder; /** indicates whether onRebind should be used */ boolean mAllowRebind; /** Called when the service is being created. */ @Override public void onCreate() { } /** The service is starting, due to a call to startService() */ @Override public int onStartCommand(Intent intent, int flags, int startId) { return mStartMode; } /** A client is binding to the service with bindService() */ @Override public IBinder onBind(Intent intent) { return mBinder; } /** Called when all clients have unbound with unbindService() */ @Override public boolean onUnbind(Intent intent) { return mAllowRebind; } /** Called when a client is binding to the service with bindService()*/ @Override public void onRebind(Intent intent) { } /** Called when The service is no longer used and is being destroyed */ @Override public void onDestroy() { } }
مثال
این مثال از طریق گام های ساده به شما نشان می دهد که چگونه سرویس اندروید خود را ایجاد کنید. مراحل زیر را دنبال کنید تا برنامه اندرویدی را که در آموزش Hello World Example ایجاد کرده بودیم را اصلاح کنیم:
Step | Description |
۱ | با استفاده از Android StudioIDE یک پروژه جدید ایجاد کنید و نام آن را My Application تحت بسته com.example.My Application بنامید همانطور که در فصل Hello World Example توضیح داد شد. |
۲ |
فایل اصلی اکتیویتی یعنی MainActivity.java را تغییر داده و متدهای ()startService و ()stopService را به آن اضافه کنید. |
۳ | در زیر شاخه بسته com.example.My Application پروژه، یک فایل جاوای جدید با نام MyService.java ایجاد کنید. این فایل اجرا کننده متد های مربوط به سرویس اندروید خواهد بود. |
۴ | با استفاده از تگ <service…/> سرویس خود را در فایل AndroidManifest.xml تعریف کنید. یک برنامه کاربردی می تواند بدون هیچ محدودیتی یک یا چند سرویس داشته باشد. |
۵ | محتوای پیش فرض فایل res/layout/activity_main.xml را به یک لایه خطی که شامل دو دکمه است تغییر دهید. |
۶ | نیازی به تغییر هیچ ثابتی در فایل res/values/strings.xmlنیست. Android studio از مقادیر رشته ای مراقبت می کند. |
۷ | برنامه را با استفاده از شبیه ساز اندروید اجرا کنید و نتیجه تغییرات انجام شده در برنامه را بررسی کنید. |
در ادامه محتوای تغییر یافته فایل فعالیت اصلی
src/com.example.My Application/MainActivity.java را قرار داده ایم. این فایل می تواند شامل چرخه حیات هر یک از متدهای اساسی باشد. ما متدهای ()startServiceو ()stopService را برای شروع و متوقف کردن خدمات اضافه کرده ایم.
package com.example.My Application; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.content.Intent; import android.view.View; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } // Method to start the service public void startService(View view) { startService(new Intent(getBaseContext(), MyService.class)); } // Method to stop the service public void stopService(View view) { stopService(new Intent(getBaseContext(), MyService.class)); } }
کدهای زیر نیز محتوای src/com.example.My Application/MyService.java است. در این فایل می توانید یک یا چند متد مربوط به سرویس را بر حسب نیاز پیاده سازی کنید. اما فعلا برای شروع ما تنها دو متد ()onStartCommand و ()OnDestroy را پباده سازی کرده ایم.
package com.example.My Application; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.widget.Toast; public class MyService extends Service { @Override public IBinder onBind(Intent arg0) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { // Let it continue running until it is stopped. Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show(); return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show(); } }
در زیر محتوای اصلاح شده فایل AndroidManifest.xml آورده شده است. در اینجا تگ اضافه شده است که خدمات ما را شامل می شود:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.MyApplication" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="13" android:targetSdkVersion="22" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <service android:name=".MyService" /> </application> </manifest>
در زیر محتوای فایل res/layout/activity_main.xm برای دو دکمه نشان داده شده است:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Example of services" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:textSize="30dp" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Tutorials point " android:textColor="#ff87ff09" android:textSize="30dp" android:layout_above="@+id/imageButton" android:layout_centerHorizontal="true" android:layout_marginBottom="40dp" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageButton" android:src="@drawable/abc" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/button2" android:text="Start Services" android:onClick="startService" android:layout_below="@+id/imageButton" android:layout_centerHorizontal="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Stop Services" android:id="@+id/button" android:onClick="stopService" android:layout_below="@+id/button2" android:layout_alignLeft="@+id/button2" android:layout_alignStart="@+id/button2" android:layout_alignRight="@+id/button2" android:layout_alignEnd="@+id/button2" /> </RelativeLayout>
در زیر محتوای فایل res / values / strings.xml را برای تعریف دو ثابت جدید آورده ایم:
<resources> <string name="app_name">My Application</string> <string name="menu_settings">Settings</string> <string name="title_activity_main">MainActivity</string> </resources>
حال اجازه دهید برنامه Hello World! اصلاح شده مان را اجرا کنیم. من فرض می کنم شما AVD خود در را که در آموزش نصب و راه اندازی محیط برنامه نویسی اندروید ایجاد کرده بودید. برای اجرای برنامه از Android studio، یکی از فایل های فعالیت (اکتیویتی) پروژه خود را باز کنید و بر روی آیکون Run آندروید از نوار ابزار کلیک کنید. اندروید استودیو برنامه را روی AVD شما نصب می کند و آن را شروع می کند و اگر همه چیز با نصب و برنامه شما سازگار و بدون مشکل بود، پنجره ی Emulator زیر نمایش داده خواهد شد:
حال برای شروع سرویس، بر روی دکمه Start Service کلیک کنید، که در اثر آن سرویس شروع خواهد شد. و باتوجه به کدهای نوشته شده در متد ()onStartCommand، پیام Service Started در پایین شبیه ساز به شرح زیر ظاهر خواهد شد:
برای متوقف کردن این سرویس، شما می توانید دکمه Stop Serviceکلیک کنید.