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

 (نکات تکمیلی ، 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 طولانی بنویسید (مثلا ۹ ثانیه) .>>

ادامه مطلب

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

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

سطح : پیشرفته

اساسا سرویس ها به این خاطر ساخته شده اند تا بتونیم یه سری فعالیت ها رو توی پس زمینه (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(مقید)
ادامه مطلب