آشنایی با Context در اندروید

آشنایی با Context در اندروید
آشنایی با Context در اندروید

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

اگر بخواهیم Context را تعریف کنیم میتوانیم بگوییم Context ، پی و فوندانسیون برنامه های اندرویدی است. Context وضعیت برنامه را شرح میدهد و با استفاده از آن می توان وضعیت برنامه را کنترل کرد و تغییر داد.

همچنین از Context در اکتیویتی ها، سرویس ها، broadCast reciever، فراخوانی intent، دیتابیس، SharedPreference، ساخت ویوها و ... استفاده می شود.

استفاده اشتباه از Context می تواند منجر به اشغال منابع سیستمی، کند شدن برنامه و در نهایت تجربه ای تلخ برای کاربر را در پی داشته باشد.



به صورت کلی Context ها را بر اساس نوع استفاده آنها ، تقسیم بندی می شوند:

UI Context

Non-UI Context


انواع Context
انواع Context

نوع UI Context در جاهایی استفاده می شود که با UI سروکار داریم مانند :

  • اکتیویتی ها
  • دستور YourActivity.this در اکتیویتی ها
  • دستور getContext در فرگمنت ها
  • اگر view با UI Context ساخته شده باشد دستور view.getContext نیز UI Context برمیگرداند در غیر این صورت Non-UI Context برمیگرداند.

نوع Non-UI Context : هر Context که از نوع UI Context نباشد Non-UI Context میباشد . Non-UI Context میتوانند هر کاری که UI Context ها انجام میدهند ، انجام دهد ولی این عمل توصیه نمی شود.

دستورات زیر از نوع Non-UI Context میباشد:

  • دستور getApplicationContext در اکتیویتی ها و broadCast ها و سرویس ها
  • مقدار دریافتی Context در سرویس ها و broadcast ها
  • هر شی از جنس سرویس ها
چند نکته مهم:

- نوع UI Context برای عملیات های کوتاه مدت و Non-UI Context برای عملیات های طولانی مدت است و نباید از آن ها به جای یکدیگر استفاده کرد. مثلا نباید از UI Context ها برای عملیات های طولانی مدت مثل دانلود و آپلود فایل ها و ... استفاده کرد.

- باید به خاطر داشته باشیم که نباید از Context ها به صورت استاتیک استفاده کرد چرا که باعث اشغال منابع سیستمی می شود و فضای زیادی را اشغال میکند. البته این موضوع در مورد Application context ها صدق نمیکند و در صورت لزوم میتوانیم از Application context به صورت استاتیک استفاده کنیم.

اگر برای کار با یک layout از Non Ui Context استفاده کنیم چه اتفاقی رخ می دهد؟

فقط ContextThemeWrapper و مشتقات آن از نوع UI Context می باشد و از آنجایی که کلاس Activity از ContextThemeWrapper ارث بری میکند و وقتی layout خود را inflate میکنید و با View ها کار میکنید می توانید برای آنها Theme تعریف کنید. اگر از Non UI Context برای ایجاد View استفاده کنید دیگر قادر به تعریف Theme نیستید.

آیا می توان از UI Context برای دسترسی به recources مثل color و strings و ... استفاده کرد؟

از آنجایی که UI Context = Context + Theme می باشد پس شما می توانید از Context ها برای دسترسی به منابع استفاده کنید.

آیا می توان از UI Context برای عملیات هایی مثل دانلود استفاده کرد؟

یکی از بزرگترین اشتباهاتی که ممکن است برنامه نویسان اندروید انجام دهند همین موضوع هست . استفاده از UI Context برای عملیات های طولانی مدت مثل دانلود و آپلود باعث اشغال حجم سنگینی از منابع سیستمی می شود و سیستم عامل را با کمبود منابع رو به رو میکند که همین موضوع موجب memory leake و خطای out of memory می شود.

هر برنامه نویسی اندرویدی با خطای out of memory موجه شده است از برخورد با این نوع خطاها شرمنده نباشید. برخورد شما با خطاهای مختلف با تجربه و مهارت شما نسبت عکس دارد و هرچه تجربه و مهارت های شما بیشتر شود طبیعتا باید کمتر درگیر این نوع خطاها شوید.



تقریبا در همه جای اندروید نیاز به Context هست برنامه نویسان مبتدی ممکن است از UI Context در موارد مختلف استفاده کنند که این موضوع می تواند دردسر ساز باشد. UI Context ماهیتی موقتی و ناپایدار هستند و هر لحظه ممکن است کاربر با جابه جا شدن بین صفحات یا خارج شدن از برنامه به حیات آنها پایان دهد لذا استفاده از UI Context ها برای امور طولانی مدت به هیچ وجه توصیه نمی شود . برای امور طولانی مدت می توانید از Service, Thread, AsyncTask, BroadCast و ... استفاده کنید.

در استفاده از getBaseContext دقت کنید.

در مورد getBaseContext توصیه می شود که در استفاده ازBaseContext دقت لازم را به همراه داشته باشیم زیرا که BaseContext از Object های پایه ای کلاس ContextWrapper می باشد. سیستم عامل با استفاده از Delegate Pattern از این متد در Child های بسیاری استفاده میکند و تغییرات آن بر بخش های مختلفی تاثیر گذار خواهد بود. استفاده از BaseContext فقط باید در Object هایی باشد که مستقیما از جنس ContextWrapper هست پس می توان نتیجه بگیریم مجاز به ارسال این متد به View ها نمی باشیم :

TextView textview = new TextView(getBaseContext());

استفاده از getBaseContext در مواردی شبیه به نمونه کد بالا اشتباه می باشد.

کتابخانه هایی مثل Calligraphy که در زمینه فونت کاربرد دارند از BaseContext استفاده میکنند که این موضوع منطقی و اصولی است.