آموزش برنامه نویسی اندروید قسمت هفدهم

1395/1/12 --- 3417

سلام خدمت دوستان. مقاری هستم و با هم آموزش جلسه 17 اندروید رو شروع میکنیم.

با عرض  پوزش بابت وقفه ای که بین آموزشها اتفاق افتاد به علت کمبود وقتی که داشتم،  جلسه 17 آموزش اندروید رو شروع میکنیم و انشالله سعی میکنم که ازین به بعد آموزشها به روال منظم قبل برگردد.

خب تا اینجا رسیده بودیم که یک بازگشت داشتیم به جلسات قبلی تا مطالب بسته ای که گذاشته بودم رو مثل همیشه برای شما باز کنم. که به بحث Thread رسیدیم. پیش زمینه اش مطالبی از کلاسهای انتزاعی و interface ها بود.

در نهایت به این نتیجه رسیدیم که وقتی کدی رو داخل Thread مینوشتیم (برای مثلا ایجاد وقفه ای جهت ساخت صفحه Splash) نمیتوانست با UI (ظاهر و واسط کاربری برنامه) ارتباط برقرار کند و درنتیجه برنامه کرش میکرد. سپس جهت رفع این مشکل Handler ها رو معرفی کردیم.

این جلسه به ادامه بحث میپردازیم.

اول بخش قبلی آموزش رو تکمیل کنم. اینکه چرا کد Thread معمولی اجرا نشد. المان های UI در اندروید به اصطلاح thread safe نیستند. به این منظور که اگر شما میخواهید یکی از View ها یا ابزارهای خودتان را از یک thread بجز thread اصلی برنامه تغییری بدهید، برنامه شما کرش میکند. به این  thread اصلی برنامه main thread یا UI thread میگوییم. چون تنها نخی از برنامه هست که اجازه دسترسی به UI شما را دارد. بدیهی هست! فکر کنید 3 تا نخ در برنامه موازش در حال اجرا هستند. حالا هرکدام از این نخ ها جداگانه اقدام به تغییری در View ها داشته باشند. چه شود.....

پس تنها این دسترسی به نخ اصلی داده شده است. خب برای این مشکل که بتوانید وقتی دارید برنامه ای چند نخی مینویسید آپدیتی در UI خود ایجاد کنید دو روش ارائه شده است. یکی از آنها Handler بود که آشنا شدید. روش بعدی استفاده از متد runOnUiThread هست. بصورت زیر:

آموزش برنامه نویسی اندروید قسمت هفدهم

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

1 ) Generic ها

در اصل Generic ها روشی هستند که بوسیله آنها میتوانید متدها یا سایر اجزای یک برنامه را یه شکل عمومی تعریف کنید و در جاهای مختلف و کاربردهای مختلف انواع خاصی از آنها را استفاده کنید.

مثالش را در برنامه­ های جاوایی خود دیده اید. مثلا فرض کنید میخواهیم یک List بسازیم. موقع تعریف List شما باید داخل علامت <> نوعش را مشخص کنید. مثلا:

آموزش برنامه نویسی اندروید قسمت هفدهم

به این ترتیب شما یک لیست از نوع دلخواه خود مشخص کرده اید. اگر با گرفتن دکمه Cntrl روی List وارد کلاس آن شوید میبینید:

آموزش برنامه نویسی اندروید قسمت هفدهم

یعنی با نوشتن <E> در روبروی نام کلاس میتوانید یک کلاس را Generic تعریف کنید (که البته الزامی نیست E باشد اما استفاده از این حرف مرسومتر است که مخفف Element می­باشد)

در همین حد آشنایی کافی هست

 

2 ) استفاده از Varangs برای ساخت توابعی با تعداد متغیر چندگانه

یک پروژه جاوا ساخته و متد زیر را در آن بنویسید:

آموزش برنامه نویسی اندروید قسمت هفدهم

این نوع تعریف ورودی مانند این است که شما این امکان را به متد خود بدهید تا بتواند تعداد متفاوتی ورودی  String بگیرد و شما میتوانید مثل یک آرایه با آن رفتار کنید.

بطور مثال:

آموزش برنامه نویسی اندروید قسمت هفدهم

 

حتی میتوانید مانند یک آرایه با آن برخورد کنید:

MyVarang(new String[] { "1", "2", "3" });

کار با AsyncTask

خب Async به معنای غیر همزمان است. برای تعریف یک AsyncTask به صورت زیر عمل میکنیم:

private class myAsync extends AsyncTask< params, progress, Result>

اما این ورودی ها را به ترتیب معرفی کنیم

پارامتر اول که به نام params هست مقداری هست که قرار است به تردی که میخواهیم اجرا کنیم بدهیم.

مقدار دوم Progress هست. یعنی میتوانیم به با این مقدار میزان پیشرفت کار رو نشان بدهیم. مثلا برای دانلود درصد قرار بدیم و...

مقدار سوم هم نتیجه خروجی هست. بطور مثال آدرس یک فایلی که دانلود شده و قرار هست بعنوان خروجی کار ترد درنظر گرفته شود.

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

آموزش برنامه نویسی اندروید قسمت هفدهم

خب ایراد گرفته است. دلیلش را با زدن alt+Enter متوجه میشوید. متدهایی دارد که باید implement شوند.

اگر روی AsyncTask کلید cntrl را نگه دارید و وارد کلاسش شوید میبینید که یک کلاس abstract هست:

public abstract class AsyncTask<Params, Progress, Result>

خب با زدن alt + Enter و زدن implement پنجره زیر نشان می دهد چه متد هایی باید پیاده شوند

آموزش برنامه نویسی اندروید قسمت هفدهم

مهمترین متده این کلاس! نشان دهنده کاری هست که قرار است انجام دهد. پس باید پیاده کنیدش.

@Override
protected String doInBackground(String... strings) {
    return null;
}

ورودی این متد همان مقداره اولی هست که در کلاس AsycTask تعریف کردیم. و خروجیش نیز مقداره سومی است که مشخص کردیم. و همانطور که میبینید از نوع Varang هست یعنی شما میتوانید تعداد ورودی های متفاوتی از این نوع را به آن پاس بدهید

 خب هردو اینها از نوع String بودند اما اگر بخواهیم تفاوت را حس کنیم میتوانید کد زیر را تست کنید:

private class myAsync extends AsyncTask<Integer, Double, Float>{
    @Override
    protected Float doInBackground(Integer... integers) {
        return null;
    }
}

یعنی با توجه به مقدار مشخص کردن ما این متد طبق سلیقه ما پیاده میشود.

اما AsyncTask متدهای دیگری هم دارد که هرکدام را معرفی میکنیم

@Override
protected void onProgressUpdate(Double... values) {
    super.onProgressUpdate(values);
}

این متد مشخص کننده پیشرفت کار هست همانطور که مثال زدم میتوانیم برای نشان دادن درصد پیشرفت یا انجام عملی در هربار پیشرفت کار از آن استفاده کنیم.

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

این متد برای انجام کاری پیش از شروع عملیات است. بطور مثال بخواهیم تست کنیم کاربر به اینترنت متصل هست یا نه. و....

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
}

 این متد در اصل خروجی doInBackground را بعنوان ورودی دریافت میکند. و در زمان اتمام کار اجرا میشود. خروجیه doInBackground را میتوانید در اینجا مدیریت کنید

برای درک بهتر این متدها نیاز به یک مثال عملی داریم. اما چون زمانبر هست این مثال را به جلسه بعدی واگذار میکنم در هفته آینده. خسته نباشید