همه چیز راجع به سرویس ها در اندروید (۱_۲)

 (نکات تکمیلی ، ANR ، Crash ، Service و Thread)
سطح:پیشرفته

تفاوت ANR و Crash چیست؟
ANR : ANR مخفف Android Not Responding است . همانطور که میدانید تمامی پردازش های رابط کاربری و ظاهر و UI یک اپلیکیشن در Thread (نخ) اصلی و واحد آن انجام می شود. ANR زمانی رخ می دهد که ما یک پردازش طولانی مدت (چیزی حدود ۵ ثانیه)  را در ترد  اصلی UI انجام دهیم.
که این باعث می شود تا (GUI(Graphic User Interface برنامه قفل شود و دیگر هیچ واکنشی نشان ندهد. در این صورت یک دیالوگ ظاهر می شود که از شما میخواهد یا Wait را انتخاب کنید تا شاید برنامه بتواند خودش را بازیابی کند و مجددا اجرا شود و یا Force Close را انتخاب کنید تا از برنامه خارج شود.

Crash :Crash که در لغت به معنای درهم شکستن است ناشی از یک Exception و یک error مدیریت نشده است .(منظور از مدیریت نشده این است که درون try/catch نباشد )  مثل وقتی که در برنامه یک عدد را بر صفر تقسیم کنیم یا محاسبات ریاضی بین یک رشته از حروف و یک عدد انجام دهیم یا وقتی یک آرایه ی خالی را پیمایش کنیم و…  که منجر به Crash و در نهایت Force Close برنامه می شود و معمولا از روی نوع Exception میتوان به علت خطا پی برد.

اکنون میخواهیم کاری کنیم تا در سرویس مان پروسه ای طولانی انجام شود تا منجر به خطای ANR شود .
در صفحه ی activity_main.xml همانطور که در آموزش قبل گفتیم  دو دکمه برای شروع و توقف سرویس داریم و در MainActivity.java هم دستورات StartService و StopService را برای آنها می نویسیم.
در سرویس مان برای ایجاد خطای ANR  ، هر دو ثانیه یک بار Thread.sleep را در یک حلقه ی for تا ۱۰۰ مرتبه صدا میزنیم و به ازای هر اجرای حلقه یک Log به صورت زیر  چاپ میکنیم:
<<تابع Thread.sleep عددی را بر حسب میلی ثانیه میگیرد و می توان گفت که یک پردازش را به همان میزان شبیه سازی میکند و این طبیعی است که اگر یک محاسبات و پردازش طولانی مدت در Thread اصلی داشته باشیم حافظه کم می آورد . شما همچنین می توانید for  را بردارید و یک Thread.sleep طولانی بنویسید (مثلا ۹ ثانیه) .>>

ادامه مطلب

همه چیز راجع به سرویس ها در اندروید(۲)

(سرویس های Started یا UnBounded )

سطح : پیشرفته

در این قسمت سرویس های از نوع Started  را بررسی میکنیم.

سرویس های Started و سرویس های Bounded دو چرخه ی حیات متفاوت دارند ولی هر دو در همان  thread (نخ) اصلی برنامه اجرا می شوند . پس اگر محاسبات سنگینی را بخواهیم در این سرویس پردازش کنیم بهتر است که آن را در یک thread دیگر انجام دهیم.

سرویس   Started  با صدا زدن (یا invoke) متد StartService  از سوی یک مولفه در اکتیویتی ها اجرا می شود و تا زمانی که دستور توقف آن صادر نشده است ادامه خواهد داشت، حتی اگر آن مولفه ای که آن را صدا زده است از بین برود.
برای پایان دادن به کار سرویس باید متد stopService را صدا بزنیم. همچنین یک سرویس میتواند خودش را با متد StopSelf متوقف کند.(مثلا پس از اتمام دانلود یک فایل)

البته همانطور که قبلا هم اشاره کردیم در هر شرایطی که سیستم عامل اندروید احساس کمبود فضا و منابع کند به راحتی سرویس را Kill  می کند که در آینده میگوییم چه راه حل هایی می توان برای این مشکل ارایه کرد.

اهمیتی ندارد چند بار سرویس را startService کرده باشیم برای توقف آن یک بار دستور توقف بسنده خواهد کرد.

برای ساخت یک سرویس باید یک کلاس بسازیم که از کلاس مبنای Service یا یکی از زیر کلاس های آن ارث بری کند. کلاس مبنای سرویس متدهای زیادی دارد که در چرخه ی حیات زیر (که مربوط به سرویس های Started است) میتوانید آنها راببینید:

به جز متد onBind ، پیاده سازی سایر متدها اختیاری است.

پس یک کلاس می سازیم به نام MyService و آن را از Service ارث بری می کنیم

ادامه مطلب

همه چیز راجع به سرویس ها در اندروید(۱)

(مقدمات سرویس ، سرویس چیست؟ ، تفاوت ها)

سطح : پیشرفته

اساسا سرویس ها به این خاطر ساخته شده اند تا بتونیم یه سری فعالیت ها رو توی پس زمینه (background) برای مدت نسبتا طولانی انجام بدیم. مثلا وقتی شما یه موزیک از تلفن همراهتون پخش می کنید و  همزمان در یک بازی مشغول می شوید و یا وارد اپلیکیشن های دیگر می شوید ، مدیا پلیر گوشی شما از سرویس استفاده کرده و در پس زمینه  داره دستور میده که آهنگ پخش بشه و اگر هم تمام شد به آهنگ بعدی برود و… .

یا مثلا وقتی یه فایل رو دانلود میکنید و همزمان هم کارهای دیگه ای هم انجام میدهید اینجاست که دانلود منیجر از سرویس استفاده کرده و پروسه رو در پشت صحنه ادامه میدهد.

یا وقتی میخواهید عملیات Tracking رو انجام بدبد و لحظه به لحظه لوکیشن گوشی را دریافت کنید و ذخیره کنید این سرویس است که به داد شما خواهد رسید.

پس فهمیدیم که سرویس ها بر خلاف اکتیویتی ها ظاهری ندارند و یا به اصطلاح فاقد
(ui (UserInterface هستند وهمچنین چرخه ی حیاتی متفاوت با اکتیوتی دارند.
البته به یاد داشته باشید که یک المان ظاهری مثل یک دکمه میتواند با سرویس در ارتباط باشد (با سرویس bind شود) و دستور آغاز و پایان آن را بدهد. و یا حتی یک view می تواند به طور مداوم با سرویس در ارتباط باشد. مثل یک seekbar در موزیک پلیر که هنگام پخش موزیک (وقتی که از موزیک پلیر خارج هستید) ، در پس زمینه می تواند روند پخش موزیک را در قسمت نوتیفیکیشن گوشی نمایش دهد.

یکی از اشتباهات رایج که دیده می شود اشتباه گرفتن مفهوم Thread ، Service و AsyncTask است. خوب است ابتدا اندکی به تعریف این سه مورد و تفاوت های آنها بپردازیم:
Thread: در حالت عادی هر پردازش و محاسبات و کدی که در برنامه اندروید وجود دارد در رشته و نخ اصلی (Main Thread) پشت سر هم اجرا می شود. اما اگر پردازش طولانی مدت  وزمان بری حدود ۵ ثانیه و بیشتر داشتیم (مثل گرفتن یک سری اطلاعات از سرور و یا وارد کردن تعداد زیادی اطلاعات در دیتابیس ) آن موقع است که اپلیکیشن از پس اجرای UI و فعالیت های عادی خود بر نمی آید(و به اصطلاح خطای ANR میدهد) چرا که همزمان با آن یک کار سنگین انجام می دهد.
اینجا است که از مفهمومی به نام Thread (نخ) باید استفاده کرد تا محاسابات زمان بر را در یک رشته ی دیگر به طور موازی انجام دهیم.
و همچنین در Thread  جدیدی که ساختیم به طور مستقیم دسترسی به المان های UI Thread (مثل دکمه ها و عکس هاو..)، نداریم به طوری که مثلا اگر درون Thread جدید ، یک TextView را از Thread اصلی مان SetText کنیم سریعا برنامه ForceClose می شود و خطای (only the original thread that created a view hierarchy) را میدهد.(البته راه حل هایی  برای حل این مشکل مثل استفاده از handler وجود دارد).
و همچنین با بسته شدن برنامه هیچ کدام از UI Thread و Thread جدید  باقی نخواهند ماند.

AsyncTask:همان Thread بهینه سازی شده است که یک سری توابع آماده دارد ، برای اینکه بتوانید به راحتی تغییراتی را از Thread دوم روی UI Thread اعمال کنید.(مثلا لحظه به لحظه میزان دانلود یک فایل در Thread دوم را در پروگرس باری در  UI Thread نمایش دهید.)

Service:سرویس یک Thread نیست.
سرویس ربطی به پردازش موازی ندارد ( البته مثل هر فعالیتی می تواند در یک Thread  جداگانه باشد) .
سرویس لزوما با خارج شدن از اپلیکیشن متوقف نمی شود.
سرویس مثل همان Activity می باشد که بی نیاز از رابط گرافیکی است.
سرویس یکی از ۴ مولفه ی مهم اندروید یعنی Service ، Activity ، BroadCast Receiver و ContentProvider است که هنگام استفاده از آنها باید در AndroidManifest معرفی شوند.

نکته: وقتی پلیکیشن به طور کامل از بین می رود ; سرویس ، Theread و یا AsyncTask از بین خواهند رفت !

خب اما طبق مستندات گوگل ، سرویس ها در اندروید به سه نوع تقسیم می شوند:

  • Scheduled(زمان بندی شده)
  • Started(آغاز شده)
  • Bound(مقید)
ادامه مطلب

شروع به کار ImAndroid

به نام خدای برنامه نویس ها

قصد دارم لابلای کارها و کد زدن ها تجربه ها و مطالبی که واسه خودم جالب هستند رو اینجا بنویسم
همانا که شاید برای کسی مفید واقع بشه… 🙂

فعلا که تصمیمم بر اینه که پست های این بلاگ حول آموزش باشند ولی شاید در آینده پست های دیگری هم بگذارم که مطلقا آموزش نیستند ولی میتونند مفید باشن…
در ابتدای پست های آموزش سطح اون آموزش رو مشخص می کنم که البته نسبی و تقریبی هستش ولی بعضی اوقات میتونه برای خواننده حس بهتری ایجاد کنه.

 

ادامه مطلب