وبسایت شخصی حسن هاشمی

برنامه نویس. ایران. قم :))

مروری بر معماری اندروید - قسمت دوم

خب، توی پست قبلی در مورد خاستگاه لینوکسی اندروید و همچنین kernel مورد استفاده در اندروید صحبت کردیم. این پست به صورت کلی قراره در مورد Dalvik و قسمت سبز دیاگرام باشه.

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

محض یادآوری بذارید یه بار دیگه دیاگرام رو بذارم:

Hardware abstraction layer:

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

یعنی در واقع اون ذهنیتی که همیشه خودم ازش داشتم این بوده: لایه ای نرم افزاری که با سخت افزار ارتباط داره اما فقط از طریق درایورهای ارائه شده به کرنل.

در این لحظه ممکنه یه کم سردرگمی در مورد نحوه کار HAL و همچنین تداخلی احتمال با عملکرد کرنل براتون پیش بیاد، یه توضیح ساده از روال یه فراخوانی سخت افزاری روی میشه توی چند مرحله خلاصه کرد، توجه کنید که برای اینکه زیاد وارد جزئیات نشم تا خسته کننده نباشه براتون از یه مثال خیلی خیلی ساده شده و یکم هم فرضی استفاده می کنم:

1- کد جاوا که در لایه آبی رنگ و بالای دیاگرام قرار داره یه سرویس رو فراخوانی می کنه (مثلاً قدرت باطری فعلی که بهش وصله).

2- یه سری کلاس های بزگتری هستن که مجموعه از عملیات های مرتبط رو انجام میدن و رابط بین کد شما و HAL هستن، دوباره به صورت سنتی به این کلاس ها ServiceManager گفته میشه که البته از اسمش پیداست که دربردارنده تعدادی از متدها مرتبط هست.

به صورت سنتی توی گوگل نامگذاری این کلاس اینجوریه PowerManagerService.java.

3- سرویس های مرحله قبل با استفاده از مکانیزم JNA از یه کلاسی در PowermanagerService.cpp استفاده می کنند. خود PowerManagerService.cpp در قسمت Libraries دیاگرام قرار داره.

(یه مفهوم آشنایی هست بین تمامی زبان های مدیریت شده و امکان فراخوانی توابع native رو به جاوا میده و البته برای برنامه نویسای سی شارپ p-invoke نقطه مقابلش هست).

4-  PowerManagerService.cpp حالا از کتابخانه HAL که مورد نظر ما هست Power.c رو مستقیماً میاره سر سفره :) و Power.c هم که درایور مورد نظر kernel رو تا حالا لود کرده، کد داخل درایور رو فراخوانی می کنه و اون هم که در نهایت یه pointer به یه مقدار عددی برمی گردونه که نشاندهنده مقدار باطری باقی مانده هست.

* موتور اجرایی جاوا حالا اون مقدار رو به صورت یه Managed Type به لایه هایی پایینی برمی گردونه.


از همه اینها که بگذریم، حالا دیگه واقعاً نوبت Dalvik و Libraries هست.

Libraries در واقع خود اندروید هست! بخش های مختلف این قسمت وظایف حیاتی رو بر عهده دارن، مثلاً:

OpenGL: کتابخانه render گرافیکی مورد استفاده اندروید هست.

SurfaceManager: در واقع مسئول مدیریت خروجی گرافیکی پنجره های مختلف، در process مختلف هست. یعنی مثلا اگه شما 5 تا پنجره دارید یعنی هر کدوم یه thread دارن که داره گرافیک صفحه رو نقاشی می کنه. SurfaceManager سطوح مختلفی رو در اختیار این ها قرار میده تا روی اون کارشون رو انجام بدن و  در پایان از Render نهایی نتیجه همه اونها اطمینان حاصل کنه. 

یعنی نقاشی های هر thread میره توی یه buffer که خارج از صفحه هست و در اونجا توسط SurfaceManaer ترکیب میشن و تصویر نهایی رو تشکیل میدن.

و ... که مجال باز کردن هر کدوم توی این مطلب نیست.

(میدونم استفاده کردن از لفظ نقاشی اصلا جالب نیست اما جایگزین دیگه برای لغت Drawing توی ذهنم نبود :) ).

Dalvik و Art:

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

که به ازای هر برنامه در حال اجرا یه نمونه از Dalvik لود میشه که چیز تعجب آوری نیست، چون همه runtime ها به منظور حفاظت و ایزوله سازی برنام ها از آسیب زدن به هم، مدیریت thread هایی که توسط خود dalvik ساخته میشن (نه thread ی که توسط بخش مدیریت حافظه و پردازش لینوکس ساخته میشه ) و...  همین مکانیزم رو پیاده سازی می کنن.

Art هم که مخفف Android runtime هستش و جایگزین dalvik شد. 

شاید بعد از چند ساعت برانداز کردن سورس Dalvik و ساختار ماژول هایی که تشکیلش می دادن متوجه میشدیم که واقعاً به زمان cpu های دو هسته ای و تک هسته ای تعلق داره :) یعنی GC و Multi Tasking ی که فراهم می کنه درخور پیشرفت های سخت افزاری حال حاضر نیست. در این نقطه چون هنوز بهتون نشون ندادم چجوری اندروید روی کامپیوتر خودتون build کنید، آزمون عملی ایرادهایی که عرض کردم قابل انجام نیست اما این یه مورد رو از من بپذیرین.

پس از اینجا به بعد تمرکز می کنیم روی ART.

هدف از معماری ART از ریشه، بهبود سرعت اجرای برنامه هاست. یعنی اگه دقت کنید 

به نظرم نقطه بزرگ تغییر در art نسبت به Dalvik قابلیت Ahead of time compilation بود. (انقدر گسترده بوده که گوگل مجبور شده از Refactor کردن کد فعلی Dalvik صرف نظر کنه و با هزینه زیاد Art رو تولید کنه).

یعنی ART در زمان نصب برنامه، کد رو به کد ماشین compile می کنه.

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

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


همونجور که ملاحظه می کنید در ابتدا یه ابزاری بنام dex2oat فایل apk رو می گیره فایل دیگه به نام elf رو خروجی میده (وارد جزئیات این فایل نمیشیم چون مطلب زیاد داره). و بعد هم ادامه کار با موتور اصلی ART... 


بعد از همه اینا میخوام یه نکته پایانی رو هم اضافه کنم و اون هم اینه که هر دو ماشین مجازی dvm و art از کتابخانه استاندارد C که به صورت اختصاصی برای اندروید طراحی شده به عنوان رابط با kernel استفاده می کنن. از جمله اینا همین مربع کوچک LibC تو لایه سبز رنگ کتابخانه ها رو مشاهده می کنید.

کتابخانه استاندارد C که در اندروید بهش Bionic گفته میشه دارای توابع mAlloc و ... هست که هر دو ماشین مجازی استفاده میکنن.

 و تا جایی که من میدونم تنها تفاوتش با C Standard library اصلی، بهینه سازی های انجام شده برای کار با cpu های با سرعت پایین تر هستش.


نظرات (1) -

  • ایمان

    09/10/1394 11:36:37 ق.ظ | پاسخ به این نظر

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

Loading