(Ако ви интересуват интересни приложения за Android OS, моля разгледайте нашата секция с приложения, като зададете съответната операционна система, която ви интересува)
(Статията е възможно най-точен превод на теста проведен от Том Томпсън, който е директор Proactive Support в Freescale Semiconductor).
Сигурно си мислите, че мобилните телефони вече са пораснали, след като вече са на 25 годишна възраст. Ами това не е точно така, защото предстоят доста драматични промени, нещо като късен пубертет. Инициатор на тези промени ще е софтуерът. Нови играчи на пазара ще се опитат изцяло да променят душата на мобилните телефони, като наблегнат на потребителския интерфейс. Действително доста телефони имат отвратителен интерфейс, който затруднява ползването на устройствата, но промените ще са задвижени от далеч не алтруистични подбуди. Движеща сила ще е пазарът с над 1 милиард абонати и силно възходяща тенденция.
С пускането на iPhone на пазара през 2007 промените започнаха. Вярно е, че настоящите играчи – Symbian, Windows Mobile и Java Micro Edition не са пасивни наблюдатели. Вярно е също така, че много играчи ще се опитат да се възползват от започналите промени. Такъв е случаят с Google и тяхната разработка Android, която използва Java. Това означава неограничен брой възможни приложения.
Android e мобилна платформа разработена от Google за Open Handset Alliance. Тя е софтуер тип “open source” и разчита на други open source проекти като Linux, WebKit, SQLite и т.н., да имплементира услугите си.
На фигура 1 се вижда структурата на софтуера. На дъното на структурата, близо до силиция, е Linux ядро осигуряващо мултитаскинг, различни системни услуги и управление на процесите. То управлява всички драйвери от ниско ниво и служи като Hardware Abstraction Layer (HAL). Достъпът до всички устройства от ниско ниво трябва да минава през Android фреймуорка, а не през Linux. Над ядрото се намират слоевете на Android „runtime” и “support libraries”. “Runtime” слоят се състои от Dalvik Virtual Machine (DVM) и core libraries. DVM е „преводач” на биткодове, който осигурява независимост на Android приложенията, както при Java ME. Той е оптимизиран за вградени системи. Използва например регистър-базирани обаждания и съхранение. Освен това core libraries, които изпълняват Java способностите, са написани на “native” код. Важно е, че устройствата могат да изпълняват няколко искания на DVM, като всяко от тях контроли отделен процес. Т.е устройството може да ползва няколко приложения едновременно. Все пак трябва да отбележим, че Android e оптимизиран да работи на един екран.
Фигура 1 – Софтуерът на Android.
Suport библиотеките са написани на C/C++ и осигуряват множество услуги. Всичките са от open-source проекти. SQLite осигурява по-лека работа на релационни услуги на базата с данни. SGL се занимава с 2D векторната графика, а WebKit, който е в сърцето на Safari браузъра на iPhone, изпълнява ролята на браузър. Всяко Android приложение може да има достъп до файловата система на софтуера, но не и до файлове, които се използват от други приложения.
Следващият слой на софтуера е зает от фреймуорковете на приложенията. Те са Java базирани и осигуряват голям набор от услуги за мобилните приложения. Например:
– Activity Manager-a се грижи да всички детайли от жизнения цикъл на приложенията, включва и механизъм за запазване състоянието им.
– View System се справя с много от елементите на потребителския интерфейс, включително с действията на потребителя.
– Resource Manager се грижи за ресурсите – например графичните файлове, необходими на интерфейса
– Location Manager следи позицията на устройството
– Telephony Manager се грижи за входящите и изходящи повиквания
Тези фреймуоркове ви позволяват да променяте поведението на даден клас, или да засилвате възможностите му.
Слоят на приложенията на Android ще бъде населяван от приложения като браузър, календар, email клиент и т.н., всички написани на Java. Когато сравните жизнения цикъл на Java ME Mobile Information Device Profile (MIDP) приложение с този на Android приложение, разликата е очевидна.
Фигура 2 показва жизнения цикъл на MIDP приложение (MIDlet). Типичният мобилен телефон може да има черно-бял дисплей с резолюция 96х54 пиксела, 128 KB RAM и 256 KB неволатилна памет. На такава ограничена платформа само един MIDlet може да изпълнява команди в даден период от време. Всеки MIDlet прекарва по-голямата част от жизнения си цикъл сменяйки 2 състояния – „активно”, когато то работи и „в пауза”, когато телефонът го изключва, за да обработи дадено обаждане. Дори тогава, обаче, MIDlet-a не е напълно неактивен, в смисъл, че той може да си назначава работа, да извършва дадени операции които не се нуждаят от интерфейса.
Проблем при писането на MIDlet-и е, че неговият startApp метод е извикван всеки път, когато телефонът го връща в активно състояние. Това усложнява дизайна на MIDlet-a, тъй като често инициализиращият е поставян в startApp метода. Причината за локализирането на кода там е, че спецификацията изисква в случай на грешка в конструкторския код софтуерът да хвърли fatal exception. Това поведение отхвърля възможността за грациозно възстановяване или в действителност да се покаже на потребителя какво се е объркало. Ето защо много MIDlet приложения слагат Boolean флаг – за да може при бъдещи извиквания на startApp инициализиращият код да бъде подминат. Друго усложнение е, че няма установен механизъм за запазване на състоянието на даден MIDlet докато е в пауза. Трябва сами да запазите стойностите на ключовите променливи в RMS-а и после да ги възстановите, когато приложението стане отново активно.
Фигура 3 показва жизнения цикъл на Android приложение, наричано Activity. Диаграмата показва по-сериозните хардуерни способности на съвременните устройства. В наши дни мобилните телефони от най-висок клас могат да имат до 1GB RAM и до 16GB флаш памет. Те имат по-бързи процесори, по-големи дисплеи, камери, GPS и т.н. Допълнителните състояния в жизнения цикъл на приложенията не само се справят с някои ограничения на MIDP спецификациите, но и осигуряват поддръжка на няколко приложения едновременно.
Жизненият цикъл на дадено Activity започва с извикване на onCreate, който се справя със зададените задачи и статичните глобални инициализации. onStart() методът започва видимия жизнен цикъл на дадено Activity, като по показва своя интерфейс екран на дисплея. Извикването на onResume() кара приложението да започне интеракция с потребителя. Приложението на преден план и в активно състояние. Ако друго приложение трябва да излезе на преден план Android извиква onFreeze() метода да запази състоянието на това приложение. Android осигурява методи за поддръжка, с които лесно можете да запазвате и извиквате елементи в обекти, наречени “Bundles”. След като запазите контекста на приложението, onPause() бива извикан. Приложението спира всякакви анимации, предава променливите си в постоянната памет и влиза в пауза състояние. В този момент интерфейс прозорецът на другото приложение може да излезе на преден план и да си контактува с потребителите.
Какво се случва след това на приложението зависи от няколко неща. Ако новото приложение само частично заема дисплея, то Activity-то си седи на заден фон в състояние на пауза и потребителите могат да го извикат по всяко време. Ако пък новото приложение изцяло заема екрана, onStop() бива извикан, за да спре Activity-то. Това състояние е подобно на паузата, само че в случаите на малко памет, Android може да се освободи от прозореца. Ако по-късно Activit-то бъде извикано на преден план, то onRestart() и onStart() възстановяват прозореца и интерфейса. Ако наличната памет е наистина много малко, Android ще убие Activity-то, за да освободи памет. Ако след това потребителите включат Activitity-то, то трябва да бъде рестартирано изцяло, а контекста възстановен от споменатите Bundles. От фиг. 3 виждате, че новите методи и състояния позволяват на Аctivity-to да се възстанови, независимо дали е било спряно, паузирано или унищожено.
Android SDK е свободно за сваляне (code.google.com/android/documentation.html). Предпочитаният туулсет на дивелопъра е Eclipse 3.3, който изисква също така JDT плъгин, Java Development Kit (JDK) 5 или 6 и изборно Web Services Tool (WST).
Инсталирах софтуера на Dell Latitude с 2.4 гигахерцов Pentium 4 процесор и 512МВ RAM. В документацията на SKD-то има стъпка по стъпка обяснение, как да инсталирате необходимия софтуер и да подкарате пробното “Hello World” Android приложение. Интеграцията между Eclipse IDE и Dalvik емулатора, който завършва Android обкръжението и управлява кода за Android приложения е много добра.
Избрах приложение, което придвижва ракета около екрана за пробен проект за тестване на характеристиките на Android. Примерният Android код се оказа цяло съкровище откъм информация. Взех назаем малко код от Lunar Lander играта, както и от някои други примери като за начало.
За да пишете приложения за Android трябва да разширите Activity and add код, който да допълни вашия дизайн, както при JAVA ME. Скоро започвате да оценявате onCreate() , където може да сложите инициализиращ код с възстановяване от грешки. Тук създавате и инстанция на View, която управлява вашето приложение с интерфейса му.
Въпреки това, View едва ли ще ви е много полезно, докато не се научите да използвате XML layout файла на Android за създаване на визуални обекти и интерактивни джаджи. Този layout файл представлява XML елементи, които представят различни приспособления – бутони, кутии за въвеждане на текст и лейбъли. Поради факта, че пласмента на приложения и протичането на събития между тях е йерархичен, като подреждате XML таговете вие подреждате и screen layout-a и положението на приспособленията. XML-ът се запазва във файл в res/layout/ директорията.
За да създаде своя интерфейс, Activity-то най-напрев възлага визуалното си съдържание на View, което използва вашия XML файл. След това създава инстанция на View, използва ID номера, за да се сдобие с правилните ресурси, които обхващат layout-a. Фактът, че Android използва XML, за да подреди интерфейса, ви позволява, с известни ограничения, да бърникате кода без да модифицирате във View. Би било добре ако имате visual editor, който да ви даде представа за това, как нестинга на XML се отразява върху layout-a на интерфейса.
Направих прост layout, който изпълни екрана и представляваше background картина. Използвайки Blender3D взех 3D модел на една ракета и на направих на 2D PNG bitmap картинка. Обработването на key press-овете с Android key event handlers беше подобно на това на MIDlet-ите, като само имената на методибе бяха променени. Не отне много време и вече имах ракета, който обикалаше екрана.
Нещо, което ме притесни, беше получаването на стойностите за размера на екрана – нещо, което е от изключителна важност при правенето на дизайна на геймплея. При MIDlet-ите просто извиквате getWidth() и getHeight() за тази информация. Извикването на тези методи в андроидския View конструктор винаги даваше едни и същи стойности – 0. Причината е, че View не знае ориентацията на екрана, докато onStart() не я покаже. Когато това стане Андроид веднага извиква onSizeChanged() метода. Този метод изкарва стойностите на видимия дисплей в новата му ориентация. Следващата картинка показва как да определите размера на екрана при JAVA ME и при Android.
Вторият ми тест беше да портна JAVA ME програма, която да ползва touchscreen-a. Самата програма започва с показване на празна картинка. Когато пишете по дисплея със стилус програмата изобразява червена линия, която следва стилуса. MIDletа- използва pointerPressed(), pointerDragged(), и pointerRelease() , за да изпълни операциите. Натискане на бутон изтрива образа.
Първата разлика за портването към Android бе писането на XML layout файл, който да поддържа View генерирането на потребителски интерфейс. Втората разлика бе управлението на Bitmap обекта, който да съхранява и показва резултата от писането. Промених onSizeChanged() метода, така че при смяна на ориентацията нов Bitmap да бъде определен. Освен това, за да се гарантира, че когато ново приложение заеме екрана вашето творение ще бъде запазено добавих код към onFreeze() метода, който да Bitmap-a в Bundle, наречен “icicle.”
Третата разлика беше, че Android използва само един метод, onTouchEvent(), за да се справи с touchscreen интеракциите. За щастие лесно може да разбиете действията на стилуса – надолу, нагоре и влачене – със switch. Използвах switch за да извикам леко променени pointerPressed(), pointerDragged(), и pointerRelease() методи. Въпреки че onTouchEvent() нарежда всички движения в един ред, оригиналния pointerDragged() работи като взима новата точка и слага линия между нея и старата, която е запазена преди това. Това поведени проработи първия път на Android. Единствената промяна, която направих, бе да заменя цветовете, които отговаряха на различните действия.
Ако имате опит с JAVA ME ще имате само леки затруднения при ученето да пишете андроидски код. Ще трябва да научите какви класове имат различните методи, както и някои други чудатости на Android. Използването на screen layout за е голям плюс. Android, както и iPhone има потенциала да промени начина, по който използваме мобилните телефони.