خداحافظی با findViewById در اندروید
بیش از یک دهه است که برنامه نویسان اندروید با یک مسئله ساده ولی آزار دهنده دست و پنجه نرم می کنند به نام findViewById در اندروید که این مسئله همان گرفتن رفرنس view از لایوت xml در کلاس مربوط به آن در Activity یا Fragments در زبان های جاوا یا کاتلین است.
به عنوان یک برنامه نویس مبتدی قبلاً خیلی سردرگم می شدم زیرا SDK اندروید روش FindViewByID() را استفاده می کرد. این روش یک وظیفه جداگانه را انجام می داد و آن معرفی view در چیدمان لایوت xml بود و در صورتی که ID را پیدا نمی کرد مقدار Null را برمی گرداند که این اشتباه می تواند یک میلیارد دلار خسارت توسط ایجاد کننده آن به بار بیاورد.
در این مقاله می خواهیم در مورد چگونگی تکامل findViewById() در گذر زمان و استفاده از بهترین روش در توسعه اندروید برای دریافت رفرنس view در لایوتxml بحث کنیم.
متد findViewById :
در API 1 برای معرفی یک Id از findViewById در اندروید استفاده می شد که تنها نیاز به یک شناسه Id داشت و یک شی View را بر می گرداند.
در این روش مشکلاتی وجود داشت:
- اگر Id یک View در لایوت وجود داشته باشد و شما تعریف نکرده باشید خطای زمان کامپایل را دریافت نمی کنید. در عوض زمانی که اندروید نتواند view معرفی شده را در Activity ، Fragment یا ViewGroup پیدا کند خطای NullPointerException را در زمان اجرا صادر می کند.
- اگر یک view از نوع TextView که در لایوت xml وجود دارد را به عنوان Button تعریف کنید در زمان کامپایل هیچ خطایی دریافت نمی کنید ولی در عوض ClassCastException را دریافت می کنید زیرا یک TextView قابل تبدیل شدن به Button نیست.
این روش به طور گسترده در تکامل Andoid SDK مورد استفاده قرار می گیرد. در API26 از compileSdk این تعریف برای حذف Casting تغییر کرده است.
حالا دیگر برنامه نویسان نیازی به اضافه کردن دستی Cast به viewها ندارند. اگر شما یک Button را با ID یک TextView ارجاع دهید، Android SDK سعی در یافتن ID دکمه می کند و با پیدا نشدن آن مقدار Null را برمی گرداند.
اما در کاتلین، شما نیاز به تعریفی مانند findViewById<TextView>(R.id.txtUsername) دارید.
اگر شما view ها را برای null بودن چک نکنید ممکن است NullPointerException رخ دهد اما این روش ClassCastException استفاده شده قبلی را نمایش نمی دهد.
تحلیل
- Type-safe: قبل از API26 هیچ نوع ایمنی (Type-safe) وجود نداشت.
- Null-safe: شما باید قبل از دسترسی به مقادیر Null ، view ها را چک کنید.
- Boilerplate Code: شما باید متغیر جداگانه برای همه view های استفاده شده در لایوت xml تعریف کنید.
- Build time: هیچ تفاوتی در زمان ساخت وجود ندارد.
- Languages: هر دو زبان برنامه نویسی جاوا و کاتلین را پشتیبانی می کند.
Butterknife
بسیاری از کتابخانه ها سعی در ساده سازی استفاده از findViewById() دارند. در این زمینه کتابخانه Butterknife که توسط Jake Wharton ایجاد شده است مورد توجه برنامه نویسان قرار گرفته است.این روش یک روش استاندارد برای جلوگیری از استفاده findViewById() شده است.
این کتابخانه از annotation برای پردازش و واکشی view ه استفاده می کند که در لایوت xml از روش findViewById() استفاده شده اند و در آکولاد ایجاد شده قرار گرفته اند. استفاده از این روش آسان است و به کاهش کد برنامه نویسان کمک می کند.
این مساله تقریباً مشابه با findViewById در اندروید است. با این حال برای اجتناب از بروز خطای NullPointerException در زمان اجرا null – safety را چک می کند.
توجه: این ابزار اکنون منسوخ شده است. لطفاً برای view bindingاز راه های دیگری استفاده کنید. نسخههای موجود به کار خود ادامه خواهند داد، اما تنها اشکال حیاتی برای ادغام با AGP در نظر گرفته خواهد شد. منبع: Butterknife Github repository
تحلیل
- Type-safe: بدون type-safety از findViewById استفاده می کند.
- Null-safe: این کتابخانه قبل از دسترسی ، view ها را از نظر عدم توانایی در زمان اجرا چک می کند.
- Boilerplate Code: با تولید خودکار کد, باعث کاهش boilerplate می شود.
- Build-time: زمان ساخت به دلیل پردازش annotation تحت تأثیر قرار می گیرد.
- Languages: از زبانهای جاوا و کاتلین پشتیبانی می کند.
Kotlin Synthetics
اولین Android SDK کاتلین است. این بدین معنی است که Android SDK , APIها را از زبان کاتلین اجرا می کند و بعدها برای زبان جاوا اضافه می شود.
یکی از بزرگترین ویژگی های کاتلین روش های توسعه آن است که به کمک آن Kotlin Synthetics بوجود آمد. Kotlin Synthetics برای برنامه نویسان دسترسی مستقیم به view ها در لایوت های xml را با استفاده از auto-generated از طریق روش های توسعه کاتلین ایجاد کرده است.
Kotlin Synthetics یکبار findViewById در اندروید را فراخوانی می کند و سپس نمونه هایش را به صورت پیش فرض در HashMap ذخیره می کند.پیکربندی Cache می تواند از طریق تنظیمات Gradle به SparseArray یا بدون Cache تغییر یابد.
به طور کلی Kotlin Synthetics گزینه خوبی است زیرا type-safe است و نیاز به بررسی null بودن view ها که در برخی تنظیمات لایوت وجود دارد از طریق کاتلین ندارد و برنامه نویسان نیاز به هیچ کد اضافه ای ندارند ولی این کار تنها برای پروژه های کاتلین پشتیبانی می شود.
یه مشکل جزئی برای برنامه نویسانی که از Kotlin Synthetics استفاده می کنند وجود دارد. به عنوان مثال اگر content view را برای یک لایوت تنظیم کنید و یک ID که در لایوت دیگری وجود دارد را تایپ کنید IDE به صورت خودکار متن را کامل کرده و جمله جدید را import می کند مگر اینکه برنامه نویس بصورت دستی viewهای درست را وارد کند و هیچ راه دیگری برای این مسئله در زمان برنامه نویسی وجود ندارد.
تحلیل
Null-safe: معمولاً Null-safe است. اما اگر مشخصات view در لایوت های دیگر وجود داشته باشد یا از بین رفته باشد باید برنامه نویس از فراخوانی های امن استفاده کند یا قبل از استفاده متغیر را چک کند. برنامه نویسان می توانند از Viewهای دیگر که در لایوت ها وجود دارد و منجر به NullPointerException می شود استفاده کنند.
Boilerplate Code: Boilerplate Code در این روش Boilerplate Code به عنوان توسعه متد برای تولید خودکار کد وجود ندارد و شما می توانید با یکبار افزودن پلاگین android-kotlin-extension به فایل build.gradle از این قابلیت استفاده کنید.
- Build-time: فرقی نمی کند.
- Languages: فقط از زبان کاتلین پشتیبانی می کند.
Data Binding
کتابخانه Data Binding یک کتابخانه پشتیبان است که به شما امکان می دهد عناصر UI را در لایوت خود به منبع داده برنامه با استفاده از یک استایل تعیین شده، متصل کنید.
Data Binding از لحاظ عملکرد از سایر رویکردها بهتر است زیرا علاوه بر این که با خیال راحت آن را به منبع داده متصل می کنید می توانید همزمان داده های خود را بصورت مستقیم در لایوت xml مشاهده کنید.
شما باید لایوت را به صورت دستی برای پشتیبانی از Data Binding با تنظیم تگ < layout > انتخاب کنید.
اکنون اندروید استودیو کلاس هایی را برای لایوت های شما ایجاد می کند. به عنوان مثال اگر نام فایل xml شما activity_main.xml باشد اندروید کلاس ActivityMainBinding را در جاوا یا کاتلین ایجاد می کند. شما می توانید با استفاده از آن به viewهای لایوت بدون NullPointerException یا ClassCastException دسترسی پیدا کنید.
بهترین مزیت استفاده از Data Binding این است که به برنامه نویسان امکان می دهد تا داده ها را بدون دسترسی به فایلهای جاوا و کاتلین با استفاده از view در لایوت XML ترسیم کند. همچنین می توانید از اتصال دو طرفه برای بروزرسانی XML یا مقدار داده بدون هیچگونه listeners یا callbacks استفاده کنید.
تحلیل
- Boilerplate Code: هر فایل لایوت نیاز به تگ <layout> دارد. همچنین باید یک کلاس نمونه برای اتصال خودکار به اکتیویتی یا فرگمنت ایجاد کنید.
- Build-time: با ایجاد کلاس های ایجاد شده برای لایوت ها زمان ساخت افزایش پیدا می کند. اغلب اوقات بخاطر بروزرسانی دستی و زدن دکمه Make و تولید کلاس های جدید برای لایوت ها عملیات پردازشی کند است.
- Languages: از هر دو زبان جاوا و کاتلین پشتیبانی می کند.
View Binding
View Binding یکی از کتابخانه های Data Binding است که به تازگی در اندروید استودیو3.6 معرفی شده است. زمان ساخت بهبود یافته است و به تگ های <layout> در فایل های لایوت توجه خاصی نمی کند. این برنامه به طور پیش فرض روی تمام فایل های لایوت کار می کند.
تنها تفاوت آن با data binding در استفاده آن برای مشاهده منابع است. این کار هیچ data mapping یا اتصال دوطرفه ای را انجام نمی دهد.
در صورتی که دنبال یک روش خوب برای مشاهده view ها در فایل های لایوت هستید می توانید از ViewBinding بجای گزینه های دیگر استفاده کنید.
این قابلیت تنها روی اندروید 3 یا بالاتر کار می کند و شما می توانید با اضافه کردن این مورد به فایل build.gradle این قابلیت را در برنامه خود فعال کنید.
سپس اندروید استودیو کلاس های View Binding را برای تمام فایلهای لایوت شما ایجاد می کند و شما می توانید با استفاده از این کلاس ها دقیقاً هر آنچه که در Data Binding انجام می دادید در اکتیویتی یا فرگمنت نیز انجام دهید.
اگر می خواهید فایل های لایوت را برای مشاهده کلاس های اتصال دهنده ببینید می توانید tools:viewBindingIgnore=”true” را به فایل لایوت خود اضافه کنید.
تحلیل
- Boilerplate Code: هیچ boilerplate code به عنوان کلاس های View Binding به صورت اتوماتیک ایجاد نمی شود و شما می توانید این قابلیت را یکبار در فایل build.gradle فعال کنید.
- Build-time: هیچ تأثیری در سرعت ساخت ندارد. View Binding برای برطرف کردن مشکل اتصال Data Binding طراحی شده است پس هیچ تأثیر منفی بر روی سرعت نمی گذارد.
- Languages: از هر دو زبان جاوا و کاتلین پشتیبانی می کند.
نتیجه گیری
با نگاه کردن به همه گزینه ها به نظر می رسد که View Binding بهترین گزینه در حال حاضر است.
نتیجه گیری :
در این آموزش با بررسی روش های findViewById در اندروید برای معرفی کردن View ها در اندروید پرداختیم. نظر شما در هرکدام از این روش ها چیست ؟ و خیلی خوشحال میشویم نظر شما را بشنویم
دیدگاهتان را بنویسید