به طور مثال شما یک Thread نوشتهاید که قرار است یک پیغام الکترونیک برای شما ارسال کند، این عمل به صورت یک Thread جدا اجرا میشود. زمانی که پیغام با موفقیت ارسال شد به کاربر یک پیغام میدهد که کار با موفقیت یا شکست به هر دلیلی انجام شده و پیغام مرتبط را به کاربر نمایش میدهید. این که چه پیغامی و چگونه به کاربر نمایش داده شود به عهده کلاس Thread و متد handleMessage است.
یکی از مشکلاتی که ممکن است در حین کار با Threadها برای شما به وجود آید این است که دکمه Back زده شود یا به هر دلیلی شما از برنامه در حال اجرا خارج شوید. این کار باعث Crash کردن برنامه شما میشود و این عمل اصلا خوشایند کاربر نیست، اما چگونه مشکل را حل کنیم؟
حل این مشکل راههای مختلفی دارد؛ یک راه ساده و منطقی برای انجام این کار استفاده از یک متغیر isRunning از نوع bool است. شما هنگام کار با Thread میتوانید مقدار isRunning را بررسی کنید که اگر مقدار آن true باشد به کار خود ادامه بدهد و در صورتی که مقدار false داشت کاری انجام ندهد. به کد زیر دقت کنید:
boolean isRunning = false;
@Override
public void onCreate(Bundle ibundle){
Thread backgroundThread = new Thread(new Runable(){
@Override
public void run(){
if(isRunning)
handler.sendMessage(msg);}});
isRunning = true;
backgroundThread.start();}
@Override
public void onStop(){
super.onStop();
isRunning = false;}
میتوان شرایط دیگری را که باعث میشود متغیر isRunning را false کند، نوشت.
هفته پیش درباره این موضوع برایتان گفتیم زمانی که یک Thread کارش تمام شد به Thread اصلی اطلاع دهد و شیء Handler توسط متد handleMessage به درخواستهای رسیده پاسخ دهد و عملی را که باید برای اطلاع کاربر انجام دهد به انجام برساند، اما شما به جای استفاده از متد sendMessage برای اطلاع دادن از پایان انجام کار، میتوانید از متد post استفاده کنید. این متد یک شیء Runnable به عنوان ورودی از شما دریافت میکند سپس شما میتوانید نتیجه کار خود را در متد run شیء Runnableی که به عنوان ورودی به متد post دادهاید، انجام دهید.
وضعیت Threadها:
در اندروید ۶ وضعیت برای Threadها در نظر گرفته شده است. در زیر آنها را به اختصار شرح خواهیم داد:
BLOCKED: یک Thread منتظر است برای قفل شدن ؛ این حالت برای زمانی است که چند Thread میخواهند به یک منبع مشترک دسترسی پیدا کنند.
NEW: یک Thread ایجاد شده ولی هنوز به وسیله متد start اجرا نشده است.
RUNNABLE: یک Thread در حال اجراست.
TERMINATED: یک Thread زمانی به این حالت میرود که یا کارش تمام شده باشد یا این که به طور کامل اجرای آن ناموفق بوده و به کار خود خاتمه دادهاست.
TIMED_WAITING: یک Thread با استفاده از فراخوانی متد sleep برای زمان مشخصی به حالت تعلیق درآمده است.
WAITING: یک Thread منتظر است تا سیستم به درخواستهای دیگر پاسخ دهد ؛ این درخواستها میتواند یک درخواست I/O از سوی Thread باشد.
AsyncTask
شمارههای پیشین در مورد وظایف همروند در برنامهنویسی در ویندوز توضیح دادهایم.
همین مورد نیز در android صادق است و شما میتوانید با ایجاد یک AsyncTask عملی را که قرار است برای مدت طولانی انجام شود در آن انجام دهید و نتایج را به کاربر اطلاع دهید. دقیقا شبیه Threadها عمل میکند اما مزیت آن این است که کدنویسی شما را راحتتر میکند و از درگیر شدن با خیلی از موارد که در Threadها با آن سر و کار دارید، دور میکند.
AsyncTask یک کلاس Generic است (راجع به Generic در شمارههای پیش صحبت شده است)، برای استفاده از این کلاس باید یک کلاس بنویسید که از این کلاس به ارث رسیده باشد و نوع دادههایی را که با آن قرار است کار کنید، به آن بدهید.
این کلاس 3 نوع داده قبول میکند:
۱ – داده ورودی، ورودی متد execute این کلاس را مشخص میکند که برای اجرا شدن یک AsyncTask نیاز است، میتواند Void باشد.
۲ – مقدار progress، در زمانی که کار شما در حال انجام است میتوانید با دادن این مقدار و استفاده از متد onProgressUpdate کاربر را از وضعیت کار باخبر کنید ( به طور مثال یک ProgressBar را مقدار دهید).
۳ – داده خـــــروجی، زمـــــانی کــه متد doInBackground به کار خود پایان داد یک داده را به عنوان خروجی برمیگرداند که نتیجه کارش را نشان میدهد و در متد onPostExecute استفاده میشود (پارامتر ورودی متد onPostExecute است که در این متد به کاربر نمایش داده میشود).
امیر بهاءالدین سبطالشیخ