سلام و خسته نباشید خدمت همه
قسمت دوم از مجموعه تقلب مصاحبه شغلی برنامه نویس اندروید رو در پیش داریم که میتوانید توضیحات و قسمت اول را در لینک زیر مطالعه کنید ، امروز میریم سراغ ده سوال بعدی…

سوالات مصاحبه شغلی برنامه نویس اندروید – قسمت اول

۱۱ . در چه مواردی متد onDestroy برای یک اکتیویتی فراخوانی می شود در صورتی که هنوز و فراخوانی نشده اند ؟

هنگامی که درون متد onCreate متد finish را فراخوانی کنیم سیستم به صورت مستقیم onDestroy را فراخوانی می کند

۱۲. چرا باید setContentView در متد onCreate یک کلاس اکتیویتی فراخوانی شود ؟

متد onCreate بر خلاف متد های و ( که چند بار برای یک اکتیویتی فراخوانی می شوند ) تنها یک بار فراخوانی می شود و بهتر است که متد setContentView ( که عمل سنگینی است ) را در این متد فراخوانی کنیم

۱۳. کار onSavedInstanceState و onRestoreInstanceState در اکتیویتی چیست ؟

متد onRestoreInstanceState : وقتی که یک اکتیویتی بعد از اینکه بار قبل destroy شده بود دوباره ساخته شود ما میتوانیم وضعیت قبلی اکتیویتی را از bundle ای که سیستم به اکتیویتی پاس می دهد بازیابی کنیم
هر دو متد onCreate و onRestoreInstanceState یک bundle را از سیستم تحویل میگیرند اما چون متد onCreate هم زمانی که برای بار اول اکتیویتی ساخته می شود و هم زمانی که اکتیویتی بازسازی ( recreate ) می شود فراخوانی می شود ما برای بازیابی وضعیت اکتیویتی باید حتما null بودن bundle را قبل از استفاده کردن بررسی کنیم زیرا هنگامی که برای بار اول اکتیویتی ساخته می شود اگر bundle ای که به onCreate پاس داده شده بود null بود سیستم یک instance جدید از اکتیویتی می سازد.

متد onSavedInstanceState : این متد برای ذخیره داده ها قبل از pause شدن اکتیویتی استفاده می شود

۱۴. انواع Lunch mode در اندروید را توضیح دهید :

۱. standard : در این نوع با هر بار فراخوانی یک اکتیویتی یک instance جدید برای اکتیویتی ساخته می شود و ممکن است چندین instance از یک اکتیویتی در task های مختلف یا در همان task ساخته شود مثال :
پشته ( stack ) روبرو را برای اکتیویتی ها در نظر بگیرید : ( A -> B -> C )
حالا اگر دوباره اکتیویتی B اجرا شود ( با standard lunch mode )
پشته اکتیویتی های ما برابر روبرو می شود : ( A -> B -> C -> B )

۲. SingleTop : این نوع lunch mode همان نوع standard است با این تفاوت که اگر instance ای از همان اکتیویتی در بالای پشته ( stack ) اکتیویتی های ما قرار داشت دیگر از آن اکتیویتی instance جدیدی نمی سازد بلکه intent ای به همان اکتیویتی که وجود دارد ارسال می کند مثال :
فرض کنید پشته اکتیویتی های ما مانند روبرو است : ( A -> B -> C )
حالا در این حالت اگر دوباره اکتیویتی C اجرا شود ( با singleTop lunch mode )
پشته اکتیویتی های ما برابر روبرو می شود : ( A -> B -> C )

۳. SingleTask : همیشه task جدید ساخته می شود و instance جدید به عنوان instance ریشه ای ( root ) به task ای که ساخته شده ارسال می شود یعنی اگر اکتیویتی ای درون task وجود داشته باشد intent به onNewIntent هدایت می شود و در غیر این صورت instance جدیدی از اکتیویتی ساخته می شود . همیشه فقط یک instance از اکتیویتی وجود دارد. مثال :

فرض کنید پشته اکتیویتی های ما به صورت روبرو بود : ( A -> B -> C -> D )
حالا اگر اکتیویتی D را دوباره اجرا کنیم ( با singleTask lunch mode )
پشته ما به صورت روبرو خواهد شد : ( A -> B -> C -> D )
حالا اگر اکتیویتی B را دوباره اجرا کنیم ( با singleTask lunch mode )
پشته ما به صورت روبرو خواهد شد : ( A -> B )
اکتیویتی های C و D نابود ( destroy ) خواهند شد

۴. SingleInstance : در این نوع همیشه تنها یک instance از یک اکتیویتی می تواند درون task وجود داشته باشد و در صورتی که اکتیویتی دوباره اجرا شود instance جدیدی در یک task جدید اجرا خواهد شد ( اگر task ای وجود داشته باشد که دارای instance ای از اکتیویتی ما باشد آن task به بالای پشته task ها آورده شده و اکتیویتی از آن task اجرا می شود ) مثال :

فرض کنید پشته اکتیویتی های ما به صورت روبرو است : ( A -> B -> C -> D )
حالا اگر اکتیویتی E که lunch mode آن singleInstance است اجرا شود پشته اکتیویتی های ما به صورت زیر خواهد بود :
task1 : E
( task2 : ( A -> B -> C -> D

ببخشید که نتونستم این سوال رو خیلی خوب توضیح بدم و جواب کمی گنگ به نظر می رسه ، میتونید توضیحات خوبی رو توی این لینک بخونید =))

۱۵. واکنش اکتیویتی وقتی که کاربر صفحه گوشی را می چرخاند چیست ؟

وقتی صفحه چرخانده می شود instance فعلی اکتیویتی نابود شده و یک instance جدید از همان اکتیوتی با جهت ( orientation ) جدید ساخته می شود . هنگامی که چرخش صفحه انجام می شود ابتدا متد onRestart فراخوانی می شود. متد های یک چرخه حیات جدید مانند جریانی ( flow ) که اکتیویتی از اول با آن ساخته شده بود فراخوانی می شوند.

۱۶.چگونه از reload شدن داده ها و reset شدن صفحه هنگام چرخش جلوگیری کنیم ؟

ساده ترین رویکرد استفاده ترکیبی از ViewModel ها و onSavedInstanceState است.

ViewModel ها به اصطلاح lifeCycle-Aware هستند به عبارتی دیگر ViewModel ها هنگامی که صاحب ( owner ) آن ها به دلیل تغییر تنظیمات ( Configuration change ) مانند چرخش صفحه از بین می رود ( destroy می شود ) نابود نمی شوند و فقط instance جدید صاحب آن ها دوباره به ViewModel وصل خواهد شد یعنی اگر شما سه بار در یک اکتیویتی صفحه را بچرخانید تنها سه instance از یک اکتیویتی ساخته اید و فقط یک ViewModel دارید

روش معمول استفاده از ViewModel ها برای ذخیره داده ها هنگام تغییر تنظیمات این است که داده ها را درون ViewModel نگهداری کرده و از onSaveInstanceState برای ذخیره داده های کوچک رابط کاربری استفاده کنیم

مثلا اگر ما یک صفحه جستجو داریم که کاربر یک متن را درون ادیت تکست نوشته است و نتایج جستجو توسط یک ریسایکلر ویو نمایش داده شده است حال اگر صفحه چرخانده شود روش ایده آل جلوگیری از ریست شدن داده این است که مقادیر لیست را درون ViewModel و نوشته ای که کاربر درون ادیت تکست نوشته را توسط onSavedInstanceState ذخیره کنیم

۱۷. دو روش برای پاکسازی پشته اکتیویتی های پیشین هنگامی که اکتیویتی جدید توسط intent فراخوانی می شود را نام ببرید :

۱. استفاده از FLAG_ACTIVITY_CLEAR_TOP
۲. استفاده از FLAG_ACTIVITY_CLEAR_TASK و FLAG_ACTIVITY_NEW_TASK به صورت پیوسته

۱۸. فرق FLAG_ACTIVITY_CLEAR_TOP و FLAG_ACTIVITY_CLEAR_TASK چیست ؟

FLAG_ACTIVITY_CLEAR_TASK : این فلگ تمامی اکتیویتی های حاضر در task ( از جمله تمامی instance های کلاسی که فراخوانی شده است ) را پاک می کند و اکتیویتی که اجرا می شود ریشه ( root ) جدید یک task خالی دیگر می شود. این فلگ باید همراه فلگ FLAG_ACTIVITY_NEW_TASK استفاده شود

FLAG_ACTIVITY_CLEAR_TOP : بر خلاف فلگ قبلی این فلگ در صورتی که instance ای از آن در لیست task موجود باشد از پاک شدن باقی اکتیویتی ها از لیست task جلوگیری می کند و آن اکتیویتی ریشه لیست task می شود اما اگر instance ای از اکتیویتی که می خواهد فراخوانی شود در لیست task موجود نباشد یک instance جدید از آن اکتیویتی می سازد و آن را ریشه لیست task قرار می دهد . استفاده از FLAG_ACTIVITY_NEW_TASK به صورت پیوسته بعد از آن ، عمل خوبی است هرچند نیازی به آن نیست

۱۹. Content provider ها را توضیح دهید

یک ContentProvider داده ها را از یک اپلیکیشن به اپلیکیشنی دیگر ( هنگامی که درخواست شود ) ارائه می دهد ، دسترسی به حالت ساختارمندی از داده را مدیریت می کند و مکانیزمی برای امنیت داده ها ارائه می دهد. ContentProvider یک رابط استاندارد ( standard interface ) است که داده ها را از یک فرایند به کد در حال اجرا در فرایندی دیگر متصل می کند.

وقتی که شما به اطلاعاتی از طریق ContentProvider دسترسی پیدا کنید باید از ContentResolver در Context اپلیکیشن خود برای ارتباط با provider به عوان یک client استفاده کنید. provider اطلاعات درخواستی را از client دریافت می کند ، عملیات های درخواستی را انجام می دهد و نتایج را برمیگرداند.

۲۰. دسترسی به داده ها توسط Content Provider :

ابتدا باید مجوز های مربوط به خواندن اطلاعات را برای اپلیکیشن رو خود گرفته باشید سپس توسط فراخوانی متد getContentResolver بر ابجکت Context به ContentResolver دسترسی پیدا می کنید و داده ها را توسط یک query و متد ContentResolver.query دریافت میکنید.

متد ContentResolver.query یک cursor برمیگرداند که می توانید داده های هر ستون را توسط متد های cursor دریافت و از آن ها استفاده کنید.