ماجراهای من و کاتلین
اگر یادتون باشه آخرین نمونه پروژهای که توی گیتهاب گذاشتم (SingleAcitvityPattern) با زبان کاتلین نوشته شده بود. هدف اصلیم از این پروژه پیادهسازی الگوی Single Activity با استفاده از فرگمنتها و هدف فرعیم آشنایی بیشتر با کاتلین بود. قبلا در مورد هدف اصلی یه پست بلاگ نوشتم و الان میخوام در رابطه با هدف فرعی صحبت کنم. استفاده از کاتلین زمان بیشتری ازم گرفت ولی در عوض با نکات مختلفی آشنا شدم که در ادامه براتون تعریف میکنم.
ترکیب کاتلین و Dagger
دیروز چندساعتی درگیر این بودم که چطوری توی پروژه میتونم NavigationManager رو از طریق Dagger به فرگمنتها اینجکت کنم. با توجه به ایدهای که در مورد NavigationManager داشتم، میشه توی یه پروژه چندتا NavigationManager داشت که هرکدوم مدیریت تعدادی از فرگمنتهارو به عهده داشته باشه (اگر پست قبلی بلاگمو در مورد این پروژه خوندید و ایدهمو در رابطه با NavigationManager متوجه نشدید، دلیلش اینه توضیحش توی متن سخته! شاید بعدا یه ویدیو برای توضیحش درست کردم)، این ایده استفاده از Dagger برای اینجکت کردنو خیلی سخت کرده بود. البته توی این چند ساعت، درگیر دو تا مشکل دیگه هم داشتم.
اولین مشکل این بود که وقتی Dagger رو به پروژه اضافه کردم، موقع اجرا خطای NoClassDefFoundError میداد!!! آخرش بعد از کلی تلاش و سرچ کردن، فهمیدم مشکل از من نیست! مشکل از Dagger هست و نسخه جدید ۲٫۱۴٫۱ رو فقط به خاطر حل این مشکل ریلیز کردن.😑
مشکل دوم این بود که وقتی میخواستم بصورت همزمان دو انوتیشن @inject و یه qualifire به اسم @PerFragment رو برای یه فیلد استفاده کنم، برنامه کرش میکرد!! بعد از کلی دیباگ کردن و بررسی سورسهای جنریت شدهی Dagger، متوجه شدم qualifireیی که میذارم اصلا اثر نمیکنه، انگار وجود نداره!! در نهایت با سرچ کردن، فهمیدم اگر میخوام همچین کاری رو توی کاتلین بکنم، باید از یه انوتیشن به اسم @field استفاده کنم. وقتی کد رو به شکل زیر تغییر دادم، برنامه درست شد.
1 |
@Inject @field:PerFragment lateinit var navigationManager: NavigationManager |
این نکته رو از یه issue توی ریپوی Dagger یاد گرفتم. کلا داخل این issue در مورد Best Practiceهای استفاده از Dagger توی کاتلین صحبت میکنن. نکتههای جالبی داخلش هست.
https://github.com/google/dagger/issues/900
تفاوت onCreateView با onViewCreated
همون شبی که پروژه رو توی گیتهاب گذاشتم، شایان پوروطن لطف کرد و ۲ ۳ ساعتی در مورد جزییات پیادهسازی پروژه صحبت کردیم. جدای همه نکتههایی که ازش یاد گرفتم، یه نکته جالب و ساده هم یادم داد. قضیه این بود که من غر میزدم چرا نمیتونیم داخل متد onCreateView فرگمنت از قابلیت static layout imports کاتلین استفاده کنیم و مجبوریم بجاش کدمون رو توی متد onViewCreated بنویسم، اینجا بود که شایان بهم گفت خب درستش همینه و نه اونکاری که من تا الان میکردم😀
تا اون لحظه، هرچی سورس و مثال دیده بودم، همشون توی onCreateView کار findview رو انجام داده بودن و این باعث شده بود که فکرکنم راه درستش اینه!!! درصورتی که اشتباه بود. البته خیلی کم پیش میاد که این اشتباه باعث باگ بشه ولی بهرحال امکانش هست. دلیل اشتباه بودنش اینه که اگر layout پیچیده باشه، احتمال داره بعضی از viewها هنوز توی onCreateView ساخته نشده باشند!! برای اطمینان بیشتر باید هرکاری با view دارید، توی onViewCreated انجام بدید.
کشف ریپوهای کاتلینی-اندرویدی
چون هنوز کاتلین رو مسلط نیستم، تقریبا برای هرکاری باید توی گوگل بگردم. در حین همین گشتنها به یه اکانت organization جالب توی گیتهاب به اسم android رسیدم. دو نفر داخلش هستند، یکیش جیک وارتون هست. همین که جیک وارتون داخلشه، دیگه حجت رو بر من تموم کرد و همه ریپوهاشو بررسی کردم. دو تا ریپوی جالب پیدا کردم.
اولی android-ktx که extensionهای کاربردی اندروید هست.
https://github.com/android/android-ktx
دومی kotlin-guides که راهنمای استفاده از کاتلین در پروژههای اندروید هست.