معماری اندروید : از دالویک تا آرت

سلام به همه دوستان.

من میخواستم که اولین مقالم رو در رابطه با فریمورک فلاتر که این روزا سر و صدای خیلی زیادی به پا کرده منتشر کنم ولی دیدم که تا زمانی که مفاهیم اصلی و اولیه رو بلد نباشیم نمیتونیم روی چیزی کاملا مسلط شیم. به همین خاطر تصمیم گرفتم که توی اولین مقاله ساختار و معماری سیستم عامل اندروید رو به صورت کامل توضیح بدم و بعدش بریم سراغ فلاتر :)

خب اول با این شروع کنیم که اندروید چی هست و چه زمانی وارد بازار شده :

اگه بخوام به صورت خلاصه بگم سیستم عامل اندروید توسط گوگل در تاریخ ۵ نوامبر ۲۰۰۷ به دنیا معرفی شد. در ابتدا نام شرکت کوچکی با بنیان گذارانی به نام های اندی رابین ریچ ماینر نیک سیرز و کریس وایت بود. این شرکت در حوزه طراحی و ساخت نرم افزارهای موبایل و ساخت سیستم عامل جدیدی برای رقابت با سیستم عامل موفق آن زمان یعنی سیمبین که در گوشی های نوکیا استفاده می شد فعالیت میکرد.

امتیاز این شرکت در سال ۲۰۰۵ توسط شرکت قدرتمند گوگل با مبلغ ۵۰ میلیون دلار خریداری شد و سیستم عامل اندروید را بر پایه هسته لینوکس طراحی نمود. تقریبا هم زمان با اندروید شرکت اپل موبایل های هوشمند خود با سیستم عامل جدید خود یعنی IOS به بازار عرضه کرد و این آغاز رقابتی بزرگ در عرصه سیستم عامل های موبایل بود.

خب حالا بریم سراغ اصل کار یعنی ساختار اندروید :

ساختار سیستم عامل اندروید شامل چهار لایه است که این لایه ها عبارتند از:(البته این طرز لایه بندی اونقدر ها هم رسمی نیس چون بعضی جا ها جوری دیگر لایه بندی کردند ولی خب اصل همه لایه بندی ها یه چیز است مثل تفاوت OSI و TCP/IP در شبکه میمونه)

  • Application
  • Application Framework
  • Libraries
  • Linux Kernel

که میتونین در شکل زیر این ساختار را مشاهده کنید :)

خب به ترتیب از اولین لایه شروع میکنیم تا برسیم به تهش.

لایه Application :

این لایه قابل لمس ترین لایه برای ما کاربران گوشی های اندرویدی هست. و از طریق این لایه ما میتوانیم با گوشی خود ارتباط داشته باشیم.

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

لایه Application Framework :

این لایه بیشتر به درد برنامه نویسان اندروید میخوره .میتوان گفت که تمام ویژگی های مجموعه سیستم عامل اندروید از طریق API های نوشته شده در زبان جاوا در دسترس برنامه نویسان است.

در واقع این لایه به برنامه ما اجازه میدهد تا به سرویس های سطح بالا تر دسترسی پیدا کنند. حالا ممکنه بگین که این سرویس ها چیا هستن ؟

Activity Manager :

این سرویس همه جنبه های زمان حیات نرم افزار را کنترل می کند(life cycle) و هم چنین قابلیت navigation back-stack را فراهم میکند.

اما navigation back-stack چیه ؟ شما اگه کمی کدنویسی اندروید کار کرده باشید حتما میدونین جابجایی بین صفحات(activity) چگونه است. کنترل این صفحات با ساختمان داده پشته(stack) پیاده سازی میشود. مثلا اگه تو برنامه دیجی کالا روی محصول کلیک کنیم میره تو یه صفحه دیگه و اینجا این صفحه جدید push میشه تو پشته وحالا اگه این صفحه رو ببندید این صفحه onDestroy() اش فراخوانی میشه و باعث میشه که از پشته pop بشه و اکتیویتی قبلی دوباره بیاد بالا. تمام این کارها وظیفه Activity Manager میباشد.

Content Providers :

این سرویس به برنامه ها این اجازه را می ده تا داده ها را انتشار و با برنامه های دیگر به اشتراک بگذارند.

مثلا ما برنامه ای نوشتیم که در آن از داده های برنامه مخاطبین استفاده کرده ایم. خب این سرویس باعث شده که ما بتونیم همچین کار باحالی رو انجام بدیم.

Resource Manager :

این سرویس دسترسی به منابع غیر کد مانند رشته های محلی، گرافیک و فایل های طرح بندی را فراهم می کند. مثلا اگه ما تو کد زدن با جاوا واسه اندروید یک فایل واسه رشته هامون در نظر گرفته باشیم میتونیم با زدن کد R.id.string_name به اون رشته دسترسی داشته باشیم که اینجا R به همون resource های ما اشاره میکنه.

Notifications Manager :

این سرویس به برنامه ها این اجازه را می دهد تا اعلان ها و هشدار ها را به کاربر نمایش دهند حتی هنگام بسته بودن اپ.

View System :

از مجموعه توسعه پذیر  view ها برای طراحی ظاهر نرم افزار استفاده می کند.

لایه Libraries :

بسیاری از اجزای اصلی سیستم عامل اندروید و خدمات مانند ART(که جلوتر میگم چی هس) و ... از کد native ساخته شده اند که نیاز به کتابخانه های native در C و C ++ دارند. پلتفرم اندروید API های جاوا را فراهم می کند تا برخی از این کتابخانه های native را به برنامه ها بیفزایند. برای مثال، ما میتونیم OpenGL ES را از طریق API جاوا برای اضافه کردن پشتیبانی از نقاشی و دستکاری گرافیک های 2D و 3D در برنامه خودمون اضافه کنیم.

چندتا از کتابخونه های مهم دیگه عبارتند از :

  • Android.app
  • Android.content
  • Android.opengl
  • Android.database
  • Android.os
  • Android.text
  • Android.view
  • Android.widget
  • Android.webkit

بخش Android Runtime :

این بخش خیلی مهمیه ما برنامه اندروید رو به صورت کلاس های جاوایی مینویسیم ولی این کد جاوا چجوری روی گوشی اجرا میشه ؟

روال کار اینجوریه که ما کلاس های جاوایی خودمون رو مینویسیم بعد که ما کد جاوا رو کامپایل میکنیم به bytecode تبدیل میشن بر خلاف زبان هایی مثل c یا c++ که مستقیم به زبان ماشین تبدیل میشوند. خب حالا ما بایت کد را داریم( که اصطلاحا به بایت کد، کد قابل حمل هم میگن که از یک سری کدهای عددی فشرده، آدرس های عددی و ثابت ها تشکیل شده است) اما این کافی نیس برای اجرا روی اندروید خب پس باید چکار کرد ؟

قبل از اندروید ۵ گوگل از ماشین مجازی جاوایی به اسم دالویک برای اجرا برنامه ها استفاده میکرد اما سوال بعدی این است که دالویک چیست ؟

دالویک : برخلاف ماشین های مجازی جاوا، که پشته ای هستند، دالویک ماشینی مبتنی بر معماری ریجستری است. ماشین‌های مجازی پشته‌ایی باید از دستورات برای بارگذاری داده‌های در پشته و اعمال تغییرات بر روی آن‌ها استفاده نماید بنابراین نسبت به ماشین‌های مبتنی بر رجیستر به دستورات بیشتری برای کد سطح بالاتر نیاز دارد ولی دستورات در ماشین رجیستری باید به صورت مبدأ و مقصد باشد که منجر به بزرگ شدن دستورات خواهد شد.

این ماشین مجازی توسط دن برونستین جهت اجرا شدن برنامه ها بر روی دستگاه های مختلف با منابع محدود ساخته شد. این ماشین بر روی دستگاه های موبایلی استفاده می شود که منابع محدود با توان پردازش پایین و عمر باتری کم و حافظه اندک هستند ماشین مجازی دالویک فایل های با پسوند .dex اجرا می کند.

خب تا اینجا ما یک بایت کد که حاصل از کامپایل کد جاوا هست و یک دالویک داریم که .dex رو اجرا میکنه.

ابزارهایی وجود دارد که بایت کد ما را به فایلی با پسوند dex تبدیل میکند مانند dx و Jack که این ابزار ها توی خود اندروید هستن. حالا که کد جاوا ما به dex تبدیل شد این کد به دالویک داده میشه و دالویک اون رو اجرا میکنه به همین سادگی :)

به این کارهایی که گفتم تا در نهایت به کدی برسیم که دالویک بتونه اون رو اجرا کنه JIT compile( اختصار شده Just In Time) میگن. یعنی هر باری که ما یک اپ را روی گوشی باز میکنیم تمام کارهای گفته شده در بالا انجام میشود واسه همین بش میگن Just In Time که یعنی همون موقعی که ما اپ رو باز میکنیم کدهای ما توسط دالویک به زبان ماشین تبدیل میشه تاکید میکنم که درست در همون موقع.

ولی مشکل این دالویک چیه ؟

کد تولیدی ما باید در هر بار اجرا روی دستگاه، از یک ران‌تایم(همون فرایند دالویک) عبور کرده و پس‌از تفسیر، اجرا شود. این روش بهینه نیست و در هر بار اجرا، کل منابع سخت افزاری را درگیر می‌کند، ولی در عوض امکان تولید آسان نرم‌افزار برای دستگاه‌ها و معماری‌های مختلف را می‌دهد.

ولی گوگل که دست رو دست نمیزاره واسه همین توی نسخه ۴.۴ ،اندروید آرت(ART) رو معرفی کرد و به صورت آزمایشی در کنار دالویک در گوشی ها استفاده کرد، به گونه ای که کاربر حق انتخاب بین این دو را داشت.اما در نسخه ۵ اندروید اون رو دیگه جایگزین دالویک کرد.

نحوه عملکرد آرت : آرت به روشی کاملاً متفاوت از دالویک، نرم افزارها رو اجرا می‌کند.

در آرت بار اولی که یک نرم‌افزار نصب می‌شود، کد بایتی (ByteCode) آن را به کد ماشین (MachineCode) تبدیل می‌کند تا در واقع آن نرم‌افزار به یک نرم افزار native تبدیل شود.

با این روش جدید که کامپایل جلوتر از زمان (Ahead-Of-Time یا AOT) نام دارد، نیاز به فعال‌سازی هر باره یک ماشین مجازی یا یک کد مفسر(همون کار دالویک که هر بار باید کد ما به dex تبدیل میشد تا دالویک اون رو اجرا کنه) از بین خواهد رفت و اجرای اپلیکیشن‌ها بسیار سریع‌تر خواهد شد. طبق بررسی‌های انجام شده، زمان بازشدن نرم‌افزارها به‌طور میانگین به نصف کاهش یافته، زمان پاسخگویی دستگاه سریع‌تر شده و عمر باتری آن نیز بالا رفته‌است.

مزایای آرت : استفاده از AOT و JIT به صورت تلفیقی همچنین دارای garbage collection بهبود یافته تر و مواردی دیگر مانند پشتیبانی از اشکال زدایی بهتر و تشخیص بهتر استثنا ها و گزارش دهی بهتر crash ها.

معایب آرت : افزایش نسبی زمان اولیه برای نصب هر نرم‌افزار و همچنین افزایش فضای مورد نیاز برای ذخیره‌سازی نرم‌افزارها.

JIT vs AOT :

پس به صورت خلاصه JIT شد اینکه هر بار که ما اپی رو اجرا میکنیم یک ماشین مجازی دالویک اجرا میشه و کد جاوا ما تبدیل میشه به .dex و بعد تازه کد ما اجرا میشه ولی در AOT کد ما قبل از اجرا به زبان ماشین تبدیل میشه و دیگر برای هر بار اجرا نیاز به ماشین مجازی برای تفسیر کد نداریم.

لایه Linux Kernel :

کرنل، هسته سیستم عامل می باشد که تمام منابع سیستم را مانند پردازنده، حافظه و ... را به برنامه های دیگر اختصاص می دهد. سورس کد کرنل لینوکس شامل بیش از 21 میلیون خط کد و یکی از پر استفاده ترین سورس کد ها در دنیا می باشد.

کرنل لینوکس یک هسته سیستم عامل اپن سورس است که در سال 1991 توسط لینوس توروالدز ساخته شد و پس از او هسته لینوکس به کمک توسعه دهندگان دیگر در سراسر جهان پیشرفت داده شد. از وظایف کرنل لینوکس می توان به موارد زیر اشاره کری:

ذخیره سازی اطلاعات: حافظه با دسترسی تصادفی (رم) به منظور خواندن ونوشتن متغیر وداده ها در حافظه و دسترسی به حافظه دائمی برای ذخیره سازی و بازیابی اطلاعات بر روی ابزار های ذخیره سازی دائمی مانند هارد دیسک

مدیریت ابزار ها: مدیریت ابزار های خارجی مانند : USB، دوربین، بلوتوس، وای فای

زمان بندی کارها: تقسیم کردن زمان پردازشگر بین پردازش های مختلف و اولویت بندی کردن کار ها برای پردازش

و ...

پایه و اساس پلتفرم اندروید هسته لینوکس است. به عنوان مثال، ART به هسته لینوکس برای ویژگی هایی مانند نخ ها (threads) و مدیریت سطح پایین حافظه وابسته است.

خب دوستان این بود معرفی ساختار اندروید امیدوارم که به دردتون خورده باشه و تونسته باشم به اطلاعاتتون چیزی رو اضافه کنم.

با مقاله های بعدی من در رابطه با فلاتر همراه باشد(البته اونم از بیس شروع میکنیم.)

:)