کدنویسی جاوا در پلتفرم اندروید – بخش چهارم


در بخش سوم به توضیح تعیینکنندههای سطوح دسترسی (Access Modifiers) و قابها (Fragments) در اندروید پرداختیم. در بخش چهارم مبحث کدنویسی جاوا در پلتفرم اندروید، به توضیح رابطها (Interfaces) و حاشیهنگاریها (Annotations) در اندروید خواهیم پرداخت.
رابطها
فرض کنید فعالیت (Activity) شما دارای سه قاب فعال باشد و هر یک از آنها وظیفه مربوط به خود را انجام دهند. حال اگر نیاز باشد که این قابها از عملکرد یکدیگر در زمانهای مشخص اطلاع پیدا کنند، چه کاری باید انجام داد؟
به صورت تئوری، قابها تنها باید نسبت به وظیفه و هدف خود آگاه هستند و نیازی نیست که از وجود دیگر قابها و فعالیت آنها اطلاع داشته باشند. در واقع، مغز متفکر برنامه شما فعالیت است. فعالیت، تنها بخشی است که به همهی قابها دسترسی و از عملکرد آنها اطلاع دارد. این توضیحات در زبان جاوا معرف رابطها (Interfaces) است. یک رابط مانند یک کلاس اما بدون نیاز به پیادهسازی است. رابط به جای پیادهسازی، API عمومی تعریف میکند. سپس، کلاسها میتوانند این رابطها را اجرا کنند و از آن پس کد شما دیگر به پیادهسازیهای بههمپیوسته کلاس متکی نخواهد بود.
رابطها به اشیاء اجازه میدهند تا بدون آشکار کردن وظایف داخلی خود، به طور غیرمستقیم با دیگر اشیاء کار کنند. وسایلی را تصور کنید که ساختن آنها بسیار دشوار است اما کار کردن با آنها تقریباً آسان است. به عنوان مثال، یک خودرو، یک دستگاه تلویزیون یا حتی وسیلهای که برای خواندن این مقاله استفاده میکنید، از نمونههایی هستند که شما احتمالاً اطلاعی از نحوه عملکرد همهی اجزای داخلی آنها ندارید اما قطعاً میدانید که چگونه از آنها استفاده کنید. رابطها نیز اینگونه هستند.
در اندروید، رابطها برای تسهیل ارتباط بین قاب با فعالیت یا ارتباط قاب با قاب مفید هستند. یک رابط، مانند کد زیر عمل میکند:
public class EmbeddedFragment extends Fragment { // 1 OnItemInListSelectedListener mCallback; // 2 public interface OnItemInListSelectedListener { public void onItemInListSelected(int position); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // 3 try { mCallback = (OnItemInListSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnItemInListSelectedListener"); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_embedded, container, false); } }
به جزئیات کد بالا دقت کنید:
- در این قاب، شما به یک متغیر عضو اعلام میکنید که شیء سفارشی اجراکننده (OnItemInListSelectedListener) را ذخیره کند و نام آن را (mCallback) قرار دهد.
- سپس، رابط را ایجاد کرده و روشهای مورد نیاز را مشخص میکنید. رابط شما میتواند تعداد زیادی روش داشته باشد.
- در تابع ()onAttach که یک متد چرخه حیات قاب است، باید بررسی کنید که فعالیت قاب شما مطابق با (OnItemInListSelectedListener) اتصال یافته باشد. اگر چنین چیزی نباشد، شما با مشکل مواجه خواهید شد و برنامه به هدف خود نمیرسد. (ClassCastException)، در حین زمان اجرای کد، این مشکل را اعلام خواهد کرد. برای فهمیدن سریعتر مشکل، استفاده از این روش بهترین راه است.
نکته بعدی، نوشتن کدی است که موجب بهکارگیری رابط توسط فعالیت شود:
public class MainMenuActivity extends Activity implements EmbeddedFragment.OnItemInListSelectedListener { ... public void onItemInListSelected(int position) { // Received a message from the Fragment, you'll do something neat here } }
کلمه کلیدی (implements) در تعریف کلاس، بیان میکند که این کلاس رابط بخصوصی را اجرا خواهد کرد. در ادامه، شما نیاز دارید برای همهی متدهای مشخصشده در رابط، عمل پیادهسازی را انجام دهید. در رابط سفارشی بالا، تنها یک متد وجود دارد و شما میتوانید ببینید که این متد دارای یک اسکلت پیادهسازی در بالای قطعهکد است.
سختترین قسمت کار همینجاست اما شما هنوز هم ارتباطی بین قاب با قاب برقرار نکردهاید. فرض کنیم، شما قاب دوم (ListDetailFragment) به همراه شناساگر (fragment_list_detail) و متدی با نام (showListItemDetails(int را تعریف کردهاید. برای برقراری ارتباط بین آنها، کافی است کاری که در بخش قبلی برای برقراری ارتباط بین فعالیت و قاب انجام دادید را به همراه یکی از متدهای عمومی قاب تکرار کنید:
public void onItemInListSelected(int position) { ListDetailFragment listDetailFragment = (ListDetailFragment) getFragmentManager.findFragmentById(R.id.fragment_list_detail); listDetailFragment.showListItemDetails(position); }
به همین سادگی، شما راهی برای برقراری ارتباط بین قابها و فعالیتها ایجاد کردید.
رابطها، برای ایجاد ارتباط بین مؤلفههای مختلف، در حالی که آنها از یکدیگر جدا شده باشند، مفید هستند. یادگیری همکاری مؤلفهها با قابها و فعالیتها، بخش بسیار مهمی در ایجاد انعطافپذیری معماری برنامه شما است.
حاشیهنگاری
آیا متوجه برخی از کدهای خاص بالای برخی از نام متدها در این مقاله شدهاید؟
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }
به این کلمات که دارای پیشوند (@) هستند، حاشیهنگاری گفته میشود. حاشیهنگاریها، اطلاعات اضافی در مراحل مختلف یک برنامه را فراهم میکنند. حاشیهنگاریها در زمان اجرای برنامه، اطلاعات اضافی را برای کامپایلر فراهم کرده و حتی کدهای اضافی را تولید میکنند.
رایجترین حاشیهنگاری در اندروید، (Override@) است. Override@، به کامپایلر اطلاع میدهد که یک متد مشخص باید از سوپرکلاس بازنویسی شود. اگر متد شما چیزی را بازنویسی نکند، کامپایلر با مشکل مواجه شده و این مسئله را به شما اطلاع میدهد. این کار باعث ایجاد یک حاشیه امنیت در مقابل همهی احتمالات ممکن میشود.
یکی دیگر از حاشیهنگاریهای معروف، (TargetApi@) است. TargetApi@، این امکان را برای متدها فراهم میکند که تشخیص دهند، آنها برای استفاده در یک نسخه خاص یا جدید ایجاد شدهاند. استفاده از یک متد با این حاشیهنگاری در یک نسخه بالاتر از نسخه برنامه شما، باعث ایجاد اخطار کامپایلر مبنی بر عدم دسترسی نسخه اندروید شما به یک عملکرد خاص میشود. شما میتوانید برنامه خود را بدون توجه به این اخطار اجرا کنید اما احتمالاً در ادامه با کرش برنامه مواجه خواهید شد.
در هنگام ساخت یک برنامه اندرویدی، به احتمال زیاد به این دو حاشیهنگاری احتیاج خواهید داشت. حاشیهنگاریهای دیگری نیز وجود دارند که در صورت تمایل به یادگیری آنها، میتوانید به دستورالعملهای API اندروید مراجعه کنید. به علاوه، شما میتوانید حاشیهنگاریهای خود را برای انجام خودکار کارهای مشخص، ایجاد کد و دیگر عملکردهای مفید دیگر ایجاد کنید. یکی از مثالهای معروف در این زمینه، کتابخانه خارجی (AndroidAnnotations) است. این کتابخانه، انواع مختلفی از حاشیهنگاریهای سفارشی را برای شما فراهم میکند که باعث سادهسازی توابع چندخطی به حاشیهنگاریهای یکخطی میشوند.
سخن آخر
ساخت یک برنامه اندرویدی، به زمان، صبر و گردآوری چندین موضوع مختلف در کنار یکدیگر نیاز دارد. خوشبختانه، برخی از جنبههای مربوط به نحوه کار و ارتباط بین اندروید و جاوا را مشخص میکند. خلاصه مطالب ارائه شده در این مقاله، به صورت زیر است:
- ماشین مجازی اندروید: یکی از تفاوتهای بین جاوای استفادهشده در اندروید و جاوای استاندارد، فرآیند کامپایل کردن و ماشینهای مجازی آنها است.
- استفاده از اشیاء POJO: اشیاء معمولی و بسیار ساده جاوا، به طور گستردهای برای تشکیل اساس اشیاء مدل درون اندروید به کار میروند.
- تعیینکنندههای سطوح دسترسی: تعیین سطوح دسترسی، کلید خوانایی و درک آسان کدهای شماست.
- رابطها: یکی از موضوعات مهم در اندروید، رابطها هستند. ارجاع به اشیاء به وسیله رابطها، برای تفکیک کدها و ایجاد مؤلفههای قابل استفاده در مراحل بعدی بسیار مفید است.
- حاشیهنگاریها: شما حاشیهنگاریهای جاوای مختص اندروید را از همان روز اول یادگیری استفاده خواهید کرد.
امیدواریم این مقاله به شما در درک ارتباط بین جاوای اندروید و جاوای استاندارد کمک کرده باشد. با ارسال نظرات خود، به ما در بهبود کیفیت مطالب کمک کنید. در صورتی که تمایل دارید به سایر بخشهای این مطلب مراجعه کنید، میتوانید از لینکهای زیر استفاده نمایید:
- کدنویسی جاوا در پلتفرم اندروید -- بخش اول
- کدنویسی جاوا در پلتفرم اندروید -- بخش دوم
- کدنویسی جاوا در پلتفرم اندروید -- بخش سوم
- کدنویسی جاوا در پلتفرم اندروید -- بخش چهارم
برای یادگیری بیشتر در مورد کدنویسی جاوا و اندروید، میتوانید به آموزشهای زیر مراجعه کنید:
- آموزش مبانی برنامه نویسی شئ گرا در جاوا
- آموزش برنامه نویسی جاوا
- آموزش برنامه نویسی اندروید (Android) – مقدماتی
- آموزش برنامه نویسی اندروید (Android) – تکمیلی
#