Журнал LinuxFormat - перейти на главную

LXF160:Android-устройство

Материал из Linuxformat
Перейти к: навигация, поиск


» Изучаем внутреннее устройство системы

Содержание

Android: А что у нас внут­ри?

Ро­ман Яры­жен­ко ре­шил по­при­стальнее при­гля­деть­ся к от­ли­чи­тель­ным осо­бен­но­стям плат­фор­мы Android.

(thumbnail)
Наш эксперт. Ро­ма­на Яры­жен­ко хле­бом не кор­ми – дай по­про­бо­вать ка­кую-ни­будь эк­зо­ти­че­скую (и не очень) ОС. Же­ла­тель­но от­кры­тую.

О плат­фор­ме Android не слы­шал нын­че, ка­жет­ся, толь­ко ленивый. Это неуди­ви­тель­но – по мно­гим при­чи­нам; неко­то­рые из них бу­дут рас­смат­ри­вать­ся даль­ше. По­ка же мож­но от­ме­тить бес­пре­це­дент­ную от­кры­тость по сравнению с дру­ги­ми по­пу­ляр­ны­ми плат­фор­ма­ми (конеч­но, на мо­мент на­пи­сания ста­тьи вслед за Google ис­ход­ные ко­ды на­ча­ли от­кры­вать и дру­гие фир­мы, но Android был пер­вой лас­точ­кой). На этом всту­п­ление мож­но за­кон­чить и пе­рей­ти к пред­ме­ту на­пи­сания ста­тьи.

Ис­то­рия успе­ха

Google ку­пил стар­тап Android Inc в 2005... Нет, по­жа­луй, на­до сна­ча­ла сде­лать неболь­шой экс­курс в про­шлое. Пре­ж­де все­го от­ме­тим, что Linux стал ис­поль­зо­вать­ся в со­то­вых те­ле­фо­нах за 4 го­да до вы­пуска пер­вой вер­сии Apple iOS, то есть в 2003 го­ду. И пер­вым смарт­фо­ном (не про­то­ти­пом), в ко­то­ром офи­ци­аль­но ис­поль­зо­вал­ся Linux, был Motorola A760. В этом же го­ду свой смарт­фон на ба­зе Linux, SCH-i519, пред­ста­вил Samsung. Пред­ла­гаю рас­смот­реть пер­вый – хо­тя бы ра­ди ин­те­ре­са.

Ка­ким же он был, пер­вый смарт­фон на осно­ве Linux? MontaVista CEE 3.0 на осно­ве яд­ра 2.4.20, Intel Xscale PXA262, 16 МБ ОЗУ, 32 ПЗУ... сла­бо­ват по со­вре­мен­ным мер­кам. И несмот­ря на то, что там сто­ял Linux с QT, на нем без осо­бых те­ло­дви­жений... нель­зя бы­ло за­пускать ниче­го, кро­ме J2ME-при­ло­жений! Лад­но. Смот­рим, ска­жем, в 2005 год. В кон­це го­да был анон­си­ро­ван ки­тай­ский смарт­фон Haier N60 (пер­вый офи­ци­аль­ный Linux-смарт­фон на россий­ском рын­ке). Ха­рак­те­ри­сти­ки – про­цес­сор Intel Xscale PXA271, 312 MHz, 59 МБ ПЗУ... и опять же невоз­мож­ность за­пускать что-ли­бо, по­ми­мо J2ME.

(thumbnail)
> Cмартфон OpenMoko NEO1973.

Кар­ти­на яс­на: несмот­ря на на­ли­чие Linux в смарт­фо­нах то­го вре­мени, они бы­ли поч­ти та­ки­ми же за­кры­ты­ми, как и те, что бы­ли осно­ва­ны на про­прие­тар­ных плат­фор­мах (OSE, Nucleus...).

В ию­ле 2007 го­да фир­мой OpenMoko был вы­пу­щен смарт­фон Neo1973. Смарт­фон был пол­но­стью (за ис­клю­чением, быть мо­жет, сте­ка GSM) от­кры­тым. Но из-за то­го, что це­ле­вой ау­ди­то­ри­ей бы­ли тех­на­ри (а так­же, воз­мож­но, из-за не слишком удачной мар­ке­тин­го­вой по­ли­ти­ки), он не по­лу­чил ши­ро­ко­го рас­про­странения.

В том же 2007 го­ду Google был осно­ван OHA – Open Handset Alliance. День его осно­вания и счи­та­ет­ся на­ча­лом Android-эры.

Пер­вым уст­рой­ст­вом на осно­ве Android стал HTC Dream, он же T-Mobile G1. Сей гад­жет имел на бор­ту 192 МБ ОЗУ, 256 МБ ПЗУ, про­цес­сор Qualcomm 7201 528 МГц и QWERTY-кла­виа­ту­ру.

Возника­ет ре­зон­ный во­прос: по­че­му имен­но Android, а не ка­кой-нибудь Mizi Linux? По­ми­мо за­ку­лис­ных ин­триг Google (без ко­то­рые, как мне ка­жет­ся, дей­ст­ви­тель­но не обошлось) и про­чих кон­спи­ра­тив­ных тео­рий за­го­во­ра, име­ет­ся и вполне ре­зон­ный от­вет на этот во­прос. Про­из­во­ди­те­лей при­вле­ка­ет низ­кая стои­мость раз­ра­бот­ки. Ну еще бы – за яд­ро пла­тить не на­до, за ин­тер­фейс – то­же. А так­же, что нема­ло­важ­но, боль­шая часть фрейм­вор­ка Android кросс­плат­фор­мен­на, что, впро­чем, боль­ше ка­са­ет­ся раз­ра­бот­чи­ков ПО. Конеч­ным же поль­зо­ва­те­лям нра­вит­ся цен­тра­ли­зо­ван­ный Android Market – сво­его ро­да ре­по­зи­то­рий, идея ко­то­ро­го бы­ла под­смот­ре­на у Apple, ну а Apple же, по всей ви­ди­мо­сти, взя­ла эту идею у ди­ст­рибь­ю­то­ров Linux.

...уст­рой­ст­ва на осно­ве Android штам­пу­ют­ся де­сят­ка­ми ты­сяч в день, и не толь­ко с имениты­ми брен­да­ми (Motorola, Alcatel), но и без­вест­ны­ми фир­ма­ми. Да­вай­те же пе­рей­дем к опи­санию ар­хи­тек­ту­ры и воз­мож­но­стей этой плат­фор­мы.

Внут­реннее уст­рой­ст­во

Начнем с оче­вид­но­го. В осно­ве Android ле­жит яд­ро Linux. Нет, ис­клю­чения, конеч­но же, име­ют­ся – по­сколь­ку, стро­го го­во­ря, то, что боль­шин­ст­во поль­зо­ва­те­лей на­зы­ва­ет сло­вом «Android», тео­ре­ти­че­­ски мо­жет за­пускать­ся да­же на Windows CE. Но здесь и да­лее мы не бу­дем рас­смат­ри­вать по­доб­ные слу­чаи (точнее го­во­ря, мы бу­дем рас­смат­ри­вать Android 2.2 с ядром 2.6.39, но, ду­ма­ет­ся, все что бу­дет опи­са­но, при­менимо и к стар­шим вер­си­ям, а час­тич­но – и к млад­шим).

Ар­хи­тек­ту­ра яд­ра, в об­щем-то, та­кая же, как и вез­де (за ис­клю­чением, мо­жет быть, IPC – но IPC час­тич­но от­но­сит­ся к поль­зо­ва­тель­ско­му ре­жи­му), по­это­му мы не бу­дем на ней оста­нав­ли­вать­ся, а поднимем­ся вы­ше Од­на­ко, ес­ли это бу­дет необ­хо­ди­мо, мы опи­шем ме­ханиз­мы яд­ра – тот же IPC.

Вы­ше у нас libc. В ка­че­­ст­ве та­ко­во­го ис­поль­зу­ет­ся не glibc, а Bionic, по­стро­ен­ный на ба­зе libc BSD – Google по­счи­та­ла, что Glibc не под­хо­дит из-за тя­же­ло­вес­но­сти и ли­цен­зи­он­ных ог­ра­ничений. Но, по­сколь­ку Bionic соз­да­вал­ся с уче­том встраи­вае­мых сис­тем, раз­ра­бот­чи­кам при­шлось по­сту­пить­ся неко­то­ры­ми функ­ция­ми «стар­ше­го бра­та». Так, он не под­дер­жи­ва­ет ис­клю­чений C++, у него соб­ст­вен­ная реа­ли­за­ция pthread, вме­сто ис­поль­зо­вания, к при­ме­ру, ./etc/resolv.conf ис­поль­зу­ет­ся об­ласть раз­де­ляе­мой па­мя­ти, мно­гие функ­ции, ти­пич­ные для «на­столь­ных» ди­ст­ри­бу­ти­вов, та­кие как getpwent(), про­сто-на­про­сто от­сут­ст­ву­ют из-за спе­ци­фи­ки ар­хи­тек­ту­ры.

Что же даль­ше? А даль­ше идет слой HAL – на­бор биб­лио­тек, на­пи­сан­ный на C/C++, слу­жит для обес­пе­чения про­зрач­но­сти ра­бо­ты с обо­ру­до­ванием. И на этом же при­мер­но уровне осталь­ные Native-биб­лио­те­ки (мы не бу­дем их под­роб­но рас­смат­ри­вать, но пе­ре­чис­лим неко­то­рые) – WebKit, SSL, OpenGL ES...

Поднима­ем­ся вы­ше – на уро­вень Native-при­ло­жений. К та­ко­вым от­но­сят­ся, на­при­мер, installd – де­мон, че­рез ко­то­рый про­хо­дит уста­нов­ка па­ке­тов, и rild – де­мон-про­слой­ка ме­ж­ду ап­па­рат­но-спе­ци­фич­ным и плат­фор­мо-неза­ви­си­мым ПО GSM.

Едем даль­ше... что мы ви­дим? Ви­дим фрейм­ворк и вир­ту­аль­ную ма­ши­ну, очень по­хо­жие на JRE, но фор­маль­но им не яв­ляю­щие­ся. Тем не менее, на­бор ба­зо­вых клас­сов и син­так­сис основ­но­го язы­ка про­грам­ми­ро­вания яс­но да­ют по­нять, что в осно­ве фрейм­вор­ка ле­жит тво­рение Sun.

Но как же вы­пол­ня­ет­ся де­ление на про­цес­сы и вы­пол­ня­ет­ся ли оно во­об­ще? Для от­ве­та на пер­вый во­прос необ­хо­ди­мо от­ве­тить на вто­рой. Да, вы­пол­ня­ет­ся. Но за­чем? Не­у­же­ли нель­зя по­ло­жить­ся на фрейм­ворк? Де­ло в том, что, ес­ли на обыч­ном ком­пь­ю­те­ре про­цесс вир­ту­аль­ной ма­ши­ны Java «упа­дет», с сис­те­мой ниче­го не слу­чит­ся. А ес­ли он упа­дет на Android, где на Java на­пи­сан прак­ти­че­­ски весь средний и верхний уро­вень, то по­след­ст­вия бу­дут фа­таль­ны­ми. Та­ким об­ра­зом, раз­де­ление на про­цес­сы ока­зы­ва­ет­ся необ­хо­ди­мым. Те­перь от­ве­тим на во­прос «как?». В JRE 5 бы­ла спе­ци­фи­ка­ция Isolates, и кое-где они при­ме­ня­ют­ся до сих пор (JNode), но в JRE 6 их уб­ра­ли, а в Android ис­поль­зу­ют­ся обыч­ные Linux-про­цес­сы. Ка­ж­дый но­вый про­цесс Android по­ро­ж­да­ет­ся от­ветв­лением про­цес­са Zygote (ис­клю­чение со­став­ля­ет system_server, в ко­то­ром вы­пол­ня­ет­ся, на­при­мер, гра­фи­че­­ская под­сис­те­ма) и име­ет на­звание ви­да com.android.Launcher. Фак­ти­че­­ски, ка­ж­дый про­цесс за­пуска­ет­ся в соб­ст­вен­ной ВМ, ко­то­рая но­сит на­звание Dalvik VM. Осо­бен­но­сти Dalvik VM та­ко­вы: соб­ст­вен­ный фор­мат хранения клас­сов DEX, соб­ст­вен­ный байт-код, ре­ги­ст­ро­вая ар­хи­тек­ту­ра, а на­чи­ная с вер­сии Android 2.2 – еще и JIT-ком­пи­ля­ция.

Рас­смот­рим неко­то­рые час­ти фрейм­вор­ка, а так­же неко­то­рые спе­ци­фич­ные по­ня­тия Android.

При­ло­жения Android стро­ят­ся на осно­ве уже имею­щих­ся клас­сов. То есть, к при­ме­ру, ес­ли по­тре­бу­ет­ся раз­ра­бо­тать соб­ст­вен­ный ре­дак­тор, для это­го бе­рет­ся уже го­то­вый класс и рас­ши­ря­ет­ся/до­пол­ня­ет­ся до необ­хо­ди­мо­го. В этом (да и не толь­ко в этом) смыс­ле плат­фор­ма Android бо­лее по­хо­жа на Web-при­ло­жения и фрейм­вор­ки.

У при­ло­жения всегда есть манифест (нет-нет, это ни в ко­ем ра­зе не манифест Ком­мунисти­че­­ской пар­тии! Это все­го-на­все­го кон­фи­гу­ра­ци­он­ный файл фор­ма­та XML, ко­то­рый при сбор­ке при­ло­жения пре­об­ра­зу­ет­ся в дво­ич­ный вид). Он пред­на­зна­чен для опи­сания струк­ту­ры при­ло­жения, его при­ви­ле­гий, тре­бо­ваний к же­ле­зу... в об­щем, мно­го для че­го.

При­ло­жение мо­жет быть мно­го­уровневым. Рас­смот­рим спи­сок основ­ных клас­сов фрейм­вор­ка Android, на осно­ве ко­то­рых стро­ят­ся боль­шин­ст­во при­ло­жений (этот спи­сок да­ле­ко не пол­ный; сю­да вклю­че­ны лишь са­мые основ­ные клас­сы):

» Activity – гру­бо го­во­ря, ло­ги­ка GUI; сам гра­фи­че­­ский ин­тер­фейс опи­сы­ва­ет­ся в XML-фай­лах сло­ев. Activity досту­пен толь­ко на пе­реднем плане, во всех осталь­ных слу­ча­ях он унич­то­жа­ет­ся – ис­клю­чение со­став­ля­ет раз­ве что слу­чай, когда те­ря­ет­ся фо­кус, в этом слу­чае Activity приоста­нав­ли­ва­ет­ся.

(thumbnail)
> HTC Dream, пер­вый ком­му­ни­ка­тор на ос­но­ве Android.

В Android не реа­ли­зо­ван мно­го­окон­ный ин­тер­фейс – по той про­стой при­чине, что эк­ран не по­зво­ля­ет вме­стить боль­шое ко­ли­че­­ст­во окон. Вме­сто это­го ис­поль­зу­ет­ся мо­дель сте­ка: на вер­шине на­хо­дит­ся тот Activity, ко­то­рый сей­час на пе­реднем плане. При на­жа­тии ап­па­рат­ной кноп­ки «Back» те­ку­щий Activity унич­то­жа­ет­ся, а тот, ко­то­рый на­хо­дил­ся ниже в сте­ке, соз­да­ет­ся вновь.

» ContentProvider – ес­ли Activity мож­но счи­тать кли­ен­том, то ContentProvider в тер­ми­нах web-фрейм­вор­ков вы­пол­ня­ет­ся на сто­роне «сер­ве­ра» (на са­мом де­ле, все несколь­ко сложнее, но рас­смот­рение шаб­ло­на про­ек­ти­ро­вания MVVM вы­хо­дит за рам­ки днной ста­тьи). ContentProvider пре­достав­ля­ет Activity дан­ные и в боль­шин­ст­ве слу­ча­ев яв­ля­ет­ся оберт­кой во­круг SQLite. Вы­пол­ня­ет­ся он в кон­тек­сте тре­бую­ще­го дан­ных Activity, по­это­му не мо­жет ра­бо­тать сам по се­бе.

» BroadcastReceiver яв­ля­ет­ся некой «про­слой­кой», ко­то­рая пе­ре­хва­ты­ва­ет ши­ро­ко­ве­ща­тель­ные со­об­щения (Intents; о них чуть поз­же) и ре­ша­ет, что де­лать в от­вет. Ина­че го­во­ря, это об­ра­бот­чик со­бы­тий, ко­то­рые соз­да­ют­ся пу­тем по­сыл­ки со­об­щения ме­то­дом sendBroadcast (ли­бо sendOrderedBroadcast) со­от­вет­ст­вую­ще­го клас­са. Не­об­хо­ди­мо от­ме­тить, что эк­зем­п­ля­ры клас­са BroadcastReceiver «од­но­ра­зо­вы», т. е. их необ­хо­ди­мо ли­бо ре­ги­ст­ри­ро­вать в манифе­сте, ли­бо по­сле сра­ба­ты­вания ре­ги­ст­ри­ро­вать за­но­во (в слу­чае, ес­ли BroadcastReceiver ис­поль­зо­вал­ся в кон­тек­сте Activity).

» Service... ду­ма­ет­ся, что с этим все бо­лее-менее по­нят­но. Это ком­понент при­ло­жения, ра­бо­таю­щий в фо­но­вом ре­жи­ме и не имею­щий гра­фи­че­­ско­­го ин­тер­фей­са. При­ме­ром мо­жет слу­жить MP3-плей­ер или, до­пустим, служ­ба пре­ду­пре­ж­дения о низ­ком за­ря­де ак­ку­му­ля­то­ра. В от­ли­чие от Activities, ко­то­рые унич­то­жа­ют­ся, ес­ли поль­зо­ва­тель за­пустил дру­гое при­ло­жение, служ­бы унич­то­жа­ют­ся ли­бо са­ми, ли­бо в слу­чае, ес­ли име­ет ме­сто ис­чер­пание па­мя­ти.

Теперь, ка­жет­ся, мож­но пе­рей­ти к сле­дую­ще­му раз­де­лу дан­ной ста­тьи.

IPC и безо­пас­ность

IPC в Android до­воль­но свое­об­раз­на. По­ми­мо стан­дарт­ных средств Unix IPC (ка­на­лы, сиг­на­лы, со­ке­ты) в плат­фор­ме от Google поя­ви­лось но­вое сред­ст­во – BINDER. Но, как во­дит­ся, «Но­вое – это хо­ро­шо за­бы­тое ста­рое», по­это­му со­вер­шим крат­кий ис­то­ри­че­­ский экс­курс.

Пред­те­ча BINDER, OpenBinder, был раз­ра­бо­тан в ныне уже не су­ще­ст­вую­щей Be Inc. в пи­ку по­пыт­кам раз­ра­бот­ки объ­ект­но-ори­ен­ти­ро­ван­ной ОС. Боль­шин­ст­во из этих по­пы­ток пред­по­ла­га­ли под­держ­ку ООП ядром. OpenBinder же, на­про­тив, мог ба­зи­ро­вать­ся на су­ще­ст­вую­щих плат­фор­мах. Прак­ти­че­­ски, ана­ло­гом мо­жет слу­жить тех­но­ло­гия COM от Microsoft или (воз­мож­но, в мень­шей сте­пени) CORBA.

По­че­му имен­но BINDER, а не SysV IPC? Де­ло в том, что SysV IPC под­вер­жен утеч­кам ре­сур­сов. А одним из тре­бо­ваний к ар­хи­тек­ту­ре BINDER бы­ло как раз тре­бо­вание не до­пускать уте­чек.

По­смот­рим, как уст­ро­ен BINDER в Android. В са­мом низу ле­жит мо­дуль яд­ра, на­пи­сан­ный на C. Что де­ла­ет этот мо­дуль? Он пре­достав­ля­ет ба­зо­вые опе­ра­ции-при­ми­ти­вы над пе­ре­да­вае­мы­ми ре­сур­са­ми. Файл уст­рой­ст­ва /dev/binder под­дер­жи­ва­ет та­кие опе­ра­ции, как open, mmap, release, poll, а сам драй­вер под­дер­жи­ва­ет ioctl. Фай­ло­вые опе­ра­ции мы рас­смат­ри­вать не бу­дем, а рас­смот­рим са­мую «вкусную» – ioctl. Ар­гу­мен­ты сис­тем­но­го вы­зо­ва – код ко­ман­ды и бу­фер дан­ных. Ко­ды команд мо­гут быть та­ки­ми:

» BINDER_WRITE_READ – наи­бо­лее час­то ис­поль­зуе­мая ко­ман­да, пе­ре­да­ет па­кет(ы) дан­ных драй­ве­ру.

» BINDER_SET_MAX_THREADS – ис­поль­зу­ет­ся для за­дания мак­си­маль­но­го ко­ли­че­­ст­ва по­то­ков для ка­ж­до­го про­цес­са, ко­то­рые долж­ны от­ве­чать на за­про­сы BINDER. Ина­че го­во­ря, это ог­раничи­ва­ет чис­ло со­единений с ка­ж­дым про­цес­сом.

» BINDER_SET_CONTEXT_MGR – за­да­ет Context Manager (см. да­лее), мо­жет быть вы­полнена толь­ко один раз при за­груз­ке Android.

» BINDER_THREAD_EXIT – ис­поль­зу­ет­ся, ес­ли свя­зан­ный по­ток за­вер­шил­ся.

» BINDER_VERSION – ну... тут без ко­мен­та­ри­ев.

У чи­та­те­ля мо­жет возник­нуть ре­зон­ный во­прос: за­чем реа­ли­зо­вы­вать BINDER в ре­жи­ме яд­ра? Ес­ли не вда­вать­ся в под­роб­но­сти (а мы не бу­дем это­го де­лать, ибо раз­мер ста­тьи ог­раничен), здесь есть два от­ве­та: во-пер­вых, это да­ет вы­иг­рыш в про­из­во­ди­тель­но­сти, а во-вто­рых – по ис­то­ри­че­­ским при­чи­нам.

Вы­ше мо­ду­ля яд­ра ле­жит часть фрейм­вор­ка BINDER, реа­ли­зо­ван­ная в ре­жи­ме поль­зо­ва­те­ля и на­пи­сан­ная на C++. Здесь не име­ет­ся ниче­го та­ко­го, на что мож­но бы­ло бы об­ра­тить внимание, раз­ве что тот мо­мент, что про­грам­мы на «чис­том» C++ мо­гут ис­поль­зо­вать фрейм­ворк на­пря­мую, но при этом при­дет­ся за­но­во опи­сы­вать аб­ст­рак­ции бо­лее вы­со­ко­го уров­ня, ко­то­рые на Java уже реа­ли­зо­ва­ны.

Пе­ре­хо­дим на уро­вень Java. Тут по­яв­ля­ют­ся но­вые тер­ми­ны:

» Binder – в анг­лоя­зыч­ных ис­точниках так на­зы­ва­ет­ся как ар­хи­тек­ту­ра BINDER, так и кон­крет­ная реа­ли­за­ция ин­тер­фей­са. Са­мое вре­мя вспомнить, что «Binder» в пе­ре­во­де с анг­лий­ско­го оз­на­ча­ет... в об­щем, ве­ще­ст­во, ко­то­рое свя­зы­ва­ет. Да­лее мы бу­дем име­но­вать са­му идею, ар­хи­тек­ту­ру «свя­зы­вания» пропис­ны­ми бу­к­ва­ми – «BINDER», кон­крет­ную реа­ли­за­цию – строч­ны­ми, а в слу­чае, когда бо­лее под­хо­дя­щим бу­дет русский тер­мин, бу­дем ис­поль­зо­вать его.

» Ин­тер­фейс IBinder [IBinder interface] – стро­го оп­ре­де­лен­ный на­бор ме­то­дов, свойств и со­бы­тий, ко­то­рый мо­жет под­дер­жи­вать кон­крет­ная реа­ли­за­ция Binder.

» Объ­ект Binder [Binder Object] – эк­зем­п­ляр клас­са, ко­то­рый при­ме­ня­ет Binder. Мо­жет реа­ли­зо­вы­вать несколь­ко свя­зы­ваний.

» Мар­кер Binder [Binder Token] – уникаль­ный иден­ти­фи­ка­тор Binder.

» Объ­ек­ты Intent – объ­ек­ты, ин­кап­су­ли­рую­щие со­об­щения. Эти объ­ек­ты мо­гут ис­поль­зо­вать­ся как внут­ри од­но­го про­цес­са, так и для меж­про­цесс­но­го взаи­мо­дей­ст­вия. Не­об­хо­ди­мо от­ме­тить, что со­об­щения асин­хрон­ны. Оче­вид­но, они мо­гут ис­поль­зо­вать­ся и для опо­ве­щения о ка­ком-то со­бы­тии.

» AIDL (Android Interface Definition Language) – ис­поль­зу­ет­ся для опи­сания пре­об­ра­зо­вания объ­ек­тов Java в объ­ек­ты, ко­то­рые мо­гут пе­ре­да­вать­ся ме­ж­ду про­цес­са­ми. Пе­ре­да­вать мож­но толь­ко при­ми­ти­вы, стро­ки, спи­ски и объ­ек­ты, реа­ли­зую­щие ин­тер­фейс Parcelable. AIDL на прак­ти­ке на эта­пе ком­пи­ля­ции пре­об­ра­зу­ет­ся в код Java, ко­то­рый «за­па­ко­вы­ва­ет» и «рас­па­ко­вы­ва­ет» со­от­вет­ст­вен­но пе­ре­да­вае­мые ме­то­ду па­ра­мет­ры и воз­вра­щае­мые зна­чения в объ­ек­ты Parcel.

» Parcel – об­раз­но, упа­ков­ка для пе­ре­да­чи бо­лее слож­ных объ­ек­тов, чем при­ми­ти­вы Java. Класс дол­жен реа­ли­зо­вы­вать «за­па­ков­ку» и «рас­па­ков­ку» этих объ­ек­тов.

Чи­та­те­лю, ско­рее все­го, уже на­дое­ли все эти пе­ре­чис­ления. Тем не менее, код мы рас­смат­ри­вать не бу­дем, но и из­лишне тео­ре­ти­зи­ро­вать то­же не бу­дем. Вме­сто это­го от­ве­тим на во­прос: как же это все ра­бо­та­ет? Итак...

При за­пуске Android дис­пет­чер служб [Service Manager] ре­ги­ст­ри­ру­ет­ся в мо­ду­ле яд­ра Binder в ка­че­­ст­ве Context Manager пу­тем по­сыл­ки со­от­вет­ст­вую­ще­го ко­да ко­ман­ды, и по­лу­ча­ет иден­ти­фи­ка­тор Binder, рав­ный ну­лю. Это де­ла­ет­ся из со­об­ра­жений безо­пас­но­сти, так как «сфе­ри­че­­ский кли­ент в ва­куу­ме» не дол­жен за­ранее знать мар­кер свя­зы­вания сер­ве­ра. Все опе­ра­ции по свя­зы­ванию про­хо­дят че­рез дис­пет­чер служб.

Когда сер­вер (в ро­ли ко­то­ро­го обыч­но вы­сту­па­ет служ­ба) за­пуска­ет­ся, он вы­зы­ва­ет ме­то­д onBind и та­ким об­ра­зом ре­ги­ст­ри­ру­ет­ся в сис­те­ме. Ес­ли кли­ент хо­чет свя­зать­ся с сер­ве­ром, он вы­зы­ва­ет ме­тод bindService, сре­ди па­ра­мет­ров ко­то­ро­го име­ет­ся, в том чис­ле, и Intent, в ко­ем на­хо­дит­ся имя служ­бы. По­сле это­го, ес­ли не вда­вать­ся в техниче­­ские под­роб­но­сти, кли­ен­ту дис­пет­че­ром служб вы­да­ет­ся мар­кер Binder, с по­мо­щью ко­то­ро­го и вы­пол­ня­ют­ся дальней­шие опе­ра­ции. Ес­ли сер­вер на­хо­дит­ся в од­ном про­цес­се с кли­ен­том, мо­дуль яд­ра не ис­поль­зу­ет­ся.

В дан­ном опи­сании все очень уп­ро­ще­но (к при­ме­ру, не рас­смат­ри­ва­ет­ся, что должно по­лу­чить­ся в ре­зуль­та­те ком­пи­ля­ции AIDL-фай­ла).

Упомянем еще один ме­ханизм IPC Android – ashmem, ме­ханизм раз­де­ляе­мой па­мя­ти. Ос­нов­ное от­ли­чие его от SysV shmem – то, что име­ет­ся счет­чик ссы­лок сег­мен­тов; та­ким об­ра­зом умень­ша­ет­ся ве­ро­ят­ность утеч­ки па­мя­ти.

Теперь о прин­ци­пах безо­пас­но­сти. Безо­пас­но­сть в Android обес­пе­чи­ва­ет­ся в основ­ном при посредстве трех следующих ме­ханиз­мов:

1 По­сколь­ку уст­рой­ст­ва Android по идее од­но­поль­зо­ва­тель­ские (в са­мом де­ле, не бу­дет же среднеста­ти­сти­че­­ский поль­зо­ва­тель со­то­во­го те­ле­фо­на раз­ре­шать звонить с него дру­гим ли­цам? Со­то­вые те­ле­фо­ны нын­че – что-то на­по­до­бие пред­ме­та лич­ной ги­гие­ны), Google сде­лал «финт уша­ми» – он не стал изо­бре­тать ве­ло­си­пед, а ис­поль­зо­вал для изо­ля­ции ка­ж­до­го при­ло­жения сис­те­му UID и GID. Та­ким об­ра­зом, ес­ли ка­кое-ли­бо при­ло­жение по­про­бу­ет уда­лить или из­менить дан­ные дру­го­го, у него это­го не получится.

2 Ме­ханизм при­ви­ле­ги­ро­ван­ных API. Доступ к неко­то­рым ре­сур­сам Android, та­ким, к при­ме­ру, как те­ле­фония и SMS, ог­раничен. Это необ­хо­ди­мо, по­сколь­ку Android – сис­те­ма мно­го­за­дач­ная, а некор­рект­ное ис­поль­зо­вание дан­ных ре­сур­сов мо­жет на­вре­дить сис­те­ме, поль­зо­ва­те­лю или его ко­шель­ку. Что­бы ис­поль­зо­вать ка­кие-ли­бо при­ви­ле­гии, при раз­ра­бот­ке при­ло­жения необ­хо­ди­мо их про­пи­сать в манифе­сте.Поль­зо­ва­тель при уста­нов­ке при­ло­жения мо­жет ли­бо со­гла­сить­ся, ли­бо не со­гла­сить­ся со всем на­бо­ром при­ви­ле­гий полностью; вы­бирать их по от­дель­ности он не мо­жет. Но в неко­то­рых мо­ди­фи­ци­ро­ван­ных про­шив­ках (та­ких, например, как CyanogenMod) по­доб­ная воз­мож­ность предусмотрена.

3 И, на­конец, ка­ж­дое Android-при­ло­жение долж­но быть под­пи­са­но циф­ро­вым сер­ти­фи­ка­том (про­ве­ря­ет­ся толь­ко при уста­нов­ке). Это по­зво­ля­ет уникаль­но иден­ти­фи­ци­ро­вать ав­то­ра и, в тео­рии, долж­но пре­пят­ст­во­вать распространению вре­до­носных про­грамм. На прак­ти­ке же аб­со­лют­ное боль­шин­ст­во при­ло­жений яв­ля­ет­ся са­мо­под­пи­сан­ны­ми, в от­ли­чие от ана­ло­гич­ной сис­те­мы, на­при­мер, в Symbian, где под­пи­сан­ны­ми при­ло­жения мо­гут быть толь­ко с ис­поль­зо­ванием сер­ти­фи­ка­та от цен­тра сер­ти­фи­ка­ции, при­вя­зан­но­го к IMEI и к то­му же пре­достав­ляю­ще­го ог­раничен­ный на­бор при­ви­ле­гий (за рас­ши­рен­ный на­бор уже на­до пла­тить и, воз­мож­но, от­прав­лять под­пи­сан­ное при­ло­жение на про­вер­ку). Ав­тор не на­шел в ис­ход­ных ко­дах Android воз­мож­но­сти от­клю­чить са­мо­под­пи­сан­ные сер­ти­фи­ка­ты; су­дя по все­му, та­ко­вой там и не имеется.

Но при­шла по­ра за­круг­лять ста­тью. Ска­жем лишь, что в од­ной ста­тье труд­но опи­сать все воз­мож­но­сти то­го или ино­го про­грамм­но­го про­ек­та. Это в пол­ной ме­ре от­но­сит­ся и к Android. Мож­но лишь с тем или иным успе­хом вы­де­лить от­ли­чи­тель­ные осо­бен­но­сти плат­фор­мы, что мы и по­пы­та­лись сде­лать.

Ито­ги

В за­клю­чение следует отметить, что Google сей­час за­да­ет на­прав­ления в об­лас­ти раз­ви­тия вы­со­ких тех­но­ло­гий, и мобильных платформ это тоже касает­ся. Но что ждет Android в бу­ду­щем? Не пре­кра­тят ли его раз­ра­бот­ку в ре­зуль­та­те па­тент­ных козней «злых дя­дей» из Ред­мон­да?.. На этот во­прос мож­но бу­дет дать от­вет лет че­рез 5; по­ка же шествие Android по планете выглядит триумфальным. |

Персональные инструменты
купить
подписаться
Яндекс.Метрика