JME1 interfejs wysokiego poziom Nieznany

background image

Technologie mobilne

Laboratorium

Zadanie 1 – tworzenie interfejsu wysokopoziomowego w

technologii JME

background image

Wstęp do JME

Java Micro Edition to specyfikacja umożliwiająca tworzenie programów w języku Java
przeznaczonych na urządzenia mobilne. Urządzenia te charakteryzują się dużą różnorodnością (co
powoduje „warstwową” architekturę specyfikacji) i ograniczonymi możliwościami obliczeniowymi
oraz pamięciowymi (co wykluczyło możliwość stosowania standardowej Javy na tego typu
urządzeniach).

Urządzenia mobilne podzielono na dwie klasy, dla każdej z nich przygotowując osobną
konfigurację (tj. zbiór pakietów wspólny dla wszystkich urządzeń z danej klasy) i związaną z nią
maszynę wirtualną. Wyróżniamy zatem :

CDC (Connected Device Configuration ) pracującą na maszynie wirtualnej zwanej CVM →
przeznaczone dla urządzeń mobilnych „z wyższej półki”, o relatywnie dużych możliwościach
obliczeniowych i pamięciowych,

CLDC (Connected, Limited Device Configuration ) pracującą na maszynie wirtualnej KVM
→ przeznaczone dla standardowych urządzeń mobilnych.

W obrębie naszych zainteresowań znajduje się tylko CLDC. CDC nie jest konfiguracją popularną i
niewiele urządzeń ją implementuje.

Na bazie konfiguracji tworzone są profile, rozszerzające funkcjonalność konfiguracji i stanowiące
drugą warstwę architektury. Profilem przeznaczonym dla CLDC jest MIDP, występujący w dwóch
głównych wersjach (1.0 oraz 2.0, wersja 3.0 jest w trakcie opracowywania).

Trzecią warstwę stanowią pakiety opcjonalne, odpowiadające za funkcjonalność, którą posiada
tylko część urządzeń dostępnych na rynku, np. obsługa GPS, funkcje multimedialne, dostęp do
systemu plików czy obsługa Bluetooth. Całość architektury przedstawia poniższy rysunek
(widoczna również ominięta w opisie część związana z CDC).

background image

Programista tworzy aplikację bazując na konfiguracji i profilu. Aplikacja tak stworzona jest
przenośna i można ją uruchomić na wszystkich urządzeniach mobilnych z danej klasy, tj.
posiadających wymaganą wersję konfiguracji i profilu (choć czasem życie jest okrutne i
rzeczywistość nie jest zgodna z tym, co mówi specyfikacja ...). Decydując się na wykorzystanie
pakietu opcjonalnego, z oczywistych względów ograniczamy liczbę potencjalnych klientów →
możliwe będzie uruchomienie aplikacji tylko na sprzęcie wspierającym dany pakiet opcjonalny.

Należy pamiętać, że z reguły nie mamy wpływu na to, jakie konfiguracje, profile i pakiety
opcjonalne są dostępne na urządzeniu. Nie można „doinstalować” elementów, które są potrzebne do
prawidłowego działania stworzonej przez nas aplikacji. Tak więc, jeśli istnieje telefon z
konfiguracją CLDC w wersji 1.0, profilem MIDP w wersji 1.0 oraz pozbawiony pakietów
opcjonalnych, to aplikacja wymagająca MIDP 2.0 lub pakietu opcjonalnego MMAPI nie będzie na
takim urządzeniu działać !

Decydując się na rodzaj i wersję konfiguracji i profilu, a także na zbiór pakietów
opcjonalnych, z których będziemy korzystać przy tworzeniu aplikacji, jednoznacznie
definiujemy zestaw urządzeń, na których aplikacja będzie działać!

Czy to jest przenośność? Niestety, niepełna. Pracując w JME nie mamy tak dużego komfortu, jak w
przypadku w pełni przenośnej standardowej JSE, pracującej praktycznie na wszystkich
komputerach stacjonarnych, niezależnie od systemu operacyjnego.
Należy jednak pamiętać, że urządzenia mobilne są bardziej zróżnicowane. Przenośność JME jest
niepełna, ale lepszych efektów pod tym względem nie zapewni żadna inna technologia tworzenia
aplikacji na urządzenia mobilne.

Profil MIDP

Profil MIDP, bazujący na konfiguracji CLDC, jest najpopularniejszym profilem w całej specyfikacji
JME. Aplikacje tworzone w tym profilu noszą nazwę MIDletów. Filozofia ich tworzenia
przypomina tworzenie Serlvetów czy też Apletów – charakteryzują się one bowiem cyklem życia, a
programista steruje zachowaniem poprzez implementację odpowiednich metod. Możliwe stany
MIDletu oraz metody, które są wywoływane przy zmianach stanu przedstawia poniższy rysunek :

background image

MIDlet może być aktywny(active), uśpiony (paused) lub zniszczony (destroyed).
Przejścia pomiędzy stanami mogą być wymuszone przez:

platformę (np. automatyczne uśpienie działającego MIDletu, gdy dzwoni telefon)
Programista, nadpisując abstrakcyjne metody pauseApp(), destroyApp() i startApp()
swojego MIDletu określa, jakie działania mają zostać podjęte przy konkretnych zmianach
stanu (np. w pauseApp() warto zaimplementować pauzę gry – gdy zadzwoni telefon, gra nie
będzie się toczyła w tle, lecz będzie czekała na użytkownika i na wznowienie gry w
metodzie startApp())

programistę
Programista może wywołać jedną z trzech metod MIDletu: notifyDestroyed(),
notifyPaused(), resumeRequest()
. Ich wywołanie wymusi zmianę stanu. Przy tak
wymuszonej zmianie metody postaci xxxxApp() z poprzedniego punktu nie będą
automatycznie wywoływane. Trzeba je wywoływać „ręcznie”, jeśli istnieje taka potrzeba.

Aplikacje mobilne są opisywane przy użyciu deskryptorów o rozszerzeniu .JAD. Deskryptory mogą
zawierać wiele wpisów, część z nich jest wymagana, część zaś opcjonalna. Ich istnienie jest ważne,
gdyż pobranie aplikacji z internetu na urządzeniu mobilnym może być kosztowne – warto najpierw
pobrać niewielki plik opisu, który pozwoli się upewnić, że nasze urządzenie spełnia wymagania
stawiane przez aplikację, przeczytać krótki opis aplikacji itp.
Atrybuty archiwum JAD nie będą tutaj dokładniej omawiane – w ramach laboratorium będziemy
korzystali z pomocy środowiska Netbeans, co pozwoli tworzyć aplikację nawet przy niedużej
wiedzy dotyczącej plików JAD. Szczegóły dotyczące tego deskryptora zostaną przedstawione na
wykładzie.

MIDP a interfejs użytkownika

Z ekranem urządzenia mobilnego należy utożsamiać klasę Display.
Obiekt tej klasy otrzymujemy poprzez wywołanie następującej statycznej metody klasy Display:

public static Display getDisplay(MIDlet midlet)

jako parametr podając obiekt MIDlet'u.

Klasa Display posiada liczne metody, dla nas najważniejszą z nich jest metoda setCurrent(),
ustalająca, co ma być obecnie wyświetlane na ekranie. Wyświetlać można obiekty klas
wywiedzionych z klasy Displayable.

Tak więc sam ekran utożsamiamy z klasą Display. Tak rozumiany ekran, uzyskany przy pomocy
metody getDisplay(), sam decyduje, co wyświetlić w danej chwili, korzystając z metody
setCurrent(). Do wyświetlania na ekranie nadają się tylko obiekty klas wywiedzionych pośrednio
lub bezpośrednio z Displayable. Hierarchię tych klas obrazuje poniższy diagram klas.

background image

Po Displayable dziedziczą Screen i Canvas.
Potomkowie Screen to klasy służące do tworzenia interfejsu wysokiego poziomu:

TextBox służy do wypisywania dużej ilości tekstu.

Alert pozwala na wyświetlanie ostrzeżeń i komunikatów. Można sprawić, by znikał po
określonym czasie, używając metody setTimeout().

List służy do tworzenia list. Kolejne elementy listy dodajemy korzystając z metod append(),
insert()
lub set(). Można określić, który element został zaznaczony, korzystając z metody
getSelectedIndex(), ewentualnie metod isSelected() lub getSelectedFlags(), jeśli lista jest
wielokrotnego wyboru.

Form to formularz, najbardziej rozbudowana klasa spośród potomków Screen. W
formularzu można umieszczać obiekty klasy Item i jej klas pochodnych. Dodajemy je,
korzystając z metod append(), insert() oraz set() formularza.

Przy pomocy abstrakcyjnej klasy Canvas tworzymy interfejs niskiego poziomu. Zajmiemy się nim
na kolejnym laboratorium.

Znamy już podstawy działania MIDletów i główne klasy pozwalające na tworzenie interfejsu
wysokiego poziomu. Jesteśmy w stanie zaimplementować pierwszy MIDlet.

background image

Emulator pozwala zobaczyć, jak wygląda ten prosty MIDlet w akcji.

Imponujący efekt to nie jest. Spróbujmy sprawić, by MIDlet stał się bardziej interaktywny.

Sterowanie w MIDlecie odbywa się przy pomocy komend (Command). Każdy z obiektów klasy
Displayable może dodać nową komendę ( addCommand() ) i zdefiniować obiekt nasłuchujący
zdarzeń związanych z jego komendami ( setCommandListener() ), implementujący metodę
commandAction(). Obiekt nasłuchujący, wewnątrz swojej metody commandAction() ma dostęp do
parametrów, które określają:

rodzaj komendy wywołanej przez użytkownika,

background image

obiekt Displayable, którego dotyczyła ta komenda.

Komendy są zwykle wyświetlane w dolnej części ekranu. Jeśli jest ich wiele, mogą być zwijane w
formie menu. Dostępne są za pomocą przycisków funkcyjnych telefonu lub poprzez ekran
dotykowy.
Komendy posiadają etykietę tekstową, typ (np. Command.EXIT dla komend wyjścia) oraz
liczbowy priorytet (niższa liczba – większa „waga” komendy). Dwie ostatnie właściwości komend
mogą być wykorzystane przez platformę do wyboru sposobu ich wyświetlania. Komendy o
ważniejszym typie i niższej wartości priorytetu będą z reguły wyświetlane wyżej albo poza
rozwijanym menu. Niektórym typom komend mogą zostać przydzielone ikony, mogą być
wywoływane dedykowanymi klawiszami telefonu itp. Tak więc nie mamy pełnej kontroli nad
sposobem udostępnienia komend użytkownikowi. Dobrym tego dowodem jest fakt, że w przypadku
komend o typie innym niż Command.SCREEN, etykiety mogą zostać zmienione z wartości
podanych przez programistę na „predefiniowane” na danej platformie etykiety dla konkretnych
typów komend.

Korzystając z wiedzy na temat komend, można rozbudować przykładowy MIDlet.

background image

Ulepszona wersja MIDletu posiada dwie komendy. Jedna z nich, po każdym wywołaniu, dodaje do
formularza dodatkowy element (konkretnie obiekt klasy StringItem), druga powoduje wyjście z
aplikacji.
Całość wygląda tak:

background image

W przykładowym kodzie pojawiła się klasa StringItem, jedna z podklas klasy Item.
Zgodnie z tym, co zostało powiedziane wcześniej, formularze (Form) są najbardziej
zaawansowanymi potomkami klasy Screen. Można w nie wstawiać następujące elementy:

ChoiceGroup – lista wyboru,

StringItem – wyświetlanie tekstu,

ImageItem – wyświetlanie obrazka,

DateField – wyświetlanie daty,

Gauge - pasek postępu,

Spacer – pusty element, pomocny przy pozycjonowaniu pozostałych,

TextField – pole do wprowadzania tekstu,

CustomItem – klasa abstrakcyjna, do tworzenia własnych elementów.

Komendy mogą być również związane z obiektami klasy Item. Dodaje się je również korzystając z
metody addCommand(). Powinny być typu Command.ITEM. Nasłuchiwanie na zdarzenia
związane z tego typu komendami powinno być realizowane przez obiekt implementujący interfejs
ItemCommandListener.
Tego typu komendy pojawiają się wśród dostępnych komend tylko wtedy, gdy dany Item będzie
zaznaczony (uzyska „focus”). W przeciwnym wypadku użytkownik nie może ich wywołać.

Bardzo ważny jest fakt, iż zgodnie ze specyfikacją metoda commandAction() interfejsów
CommandListener oraz ItemCommandListener powinna się wykonać bardzo szybko, aby nie
powodować efektu „zamrożenia” (”zawieszenia”) urządzenia. Dlatego każde czasochłonne
działanie wewnątrz tej metody (np. komunikację z internetem, zapis w pamięci urządzenia,
liczenie dużych liczb pierwszych...) należy wykonywać w osobnym wątku! Warto to
zapamiętać, przyda się na kolejnych laboratoriach!

Pakiety JSE a pakiety JME

Bardzo niewielka część pakietów standardowej Javy została przeniesiona do Javy Micro
Edition. Dotyczy to szczególnie konfiguracji CLDC. Zawiera ona pakiety java.io, java.lang
oraz java.util, lecz i one nie są kompletne, tj. nie zawierają wszystkich klas, które są
zawarte w standardowej JSE.

Warto podkreślić brak kilku kluczowych elementów, często

używanych przez programistów Javy:

generics,

background image

większości kolekcji/kontenerów (trzeba używać przestarzałych, takich jak Vector czy
Stack...),

interfejsu Iterator (należy używać Enumeration),

liczb zmiennoprzecinkowych w starszej wersji CLDC (1.0) → pojawiły się dopiero w
CLDC 1.1.

Środowisko Netbeans

Na zajęciach zalecam stosowanie środowiska programistycznego Netbeans. Środowisko to używa
standardowej platformy przeznaczonej do programowania aplikacji mobilnych : „Java ME Platform
SDK”, zapewniając jednocześnie liczne dodatkowe możliwości, przez co praca z tym IDE jest
wygodniejsza niż bezpośrednie korzystanie z JME SDK.

Zaczynamy pracę tworząc nowy projekt z kategorii „Java ME => Mobile Application”. MIDlet
tworzymy przy użyciu polecenia „New => MIDlet”. Taki sposób postępowania powinien sprawić,
że Netbeans uzupełni za nas wszelkie niezbędne wpisy w deskryptorze JAD, co można sprawdzić
we właściwościach projektu :

Dokumentacja

Należy zaznaczyć, że duża część dokumentacji powinna być zintegrowana ze środowiskiem
Netbeans. Pokazanie podpowiedzi można wymusić kombinacją klawiszy CTRL+SPACE.

background image

Warto zaglądać do „javadoców” umieszczonych na stronie :

http://java.sun.com/javame/reference/apis/jsr118/

Można tam znaleźć wiele szczegółów nie opisanych w tej instrukcji.

Należy pamiętać, że istnieje wiele metod/konstruktorów o licznych parametrach, które nie są
wymagane, tj. można w wywołaniu użyć wartości „null”. Przykładem niech będzie konstruktor
klasy Alert o sygnaturze:

public Alert(String title,String alertText, Image alertImage, AlertType
alertType)


Można go wywołać w ten sposób, jeśli nie chcemy używać obrazka ani typu Alertu :

Alert blad = new Alert("Błąd!!!" , "Nie jest dobrze … " , null, null);

lub nawet w sposób następujący, jeśli na etapie konstrukcji nie chcemy definiować żadnych
właściwości Alertu:

Alert blad = new Alert(null , null , null, null);

Zadania do wykonania

1. Stwórz MIDlet. Wyświetl na nim pierwszy widok → formularz, który będzie służył do

wpisywania danych osobowych. Podawane mają być imię, nazwisko, wiek (przy użyciu
TextField'ów) oraz płeć (przy użyciu ChoiceGroup). Stwórz komendę „wyjście”,
odpowiedzialną za wyjście z MIDletu.

background image

2. Stwórz komendę „dalej”, odpowiedzialną za przejście do kolejnego widoku. W przypadku

formularza z danymi osobowymi, kolejnym widokiem ma być TextBox, służący do
wpisywania uwag. Przejście do tego widoku ma się odbywać tylko wówczas, gdy dane w
formularzu były poprawne (np. wiek jest poprawną liczbą całkowitą), w przeciwnym
wypadku należy przez 2 sekundy wyświetlać komunikat określający popełniony przez
użytkownika błąd. Wpisanie imienia bądź nazwiska z małej litery nie powinno stanowić
błędu. Stwórz komendę „wstecz”, pozwalającą na powrót do poprzedniego widoku.

3. Stwórz ostatni z widoków – formularz do wyświetlania wyniku działania aplikacji.

Wynikiem powinien być ciąg znaków postaci „[imię] [nazwisko] ([wiek] / [płeć]) napisał
[uwaga]”. Pierwsza litera imienia i nazwiska musi być wielka, nawet jeśli użytkownik
wpisał swoje dane używając samych małych liter. Upewnij się, że każdy z 3 głównych
widoków ma dodaną komendę „wyjdź”. Sprawdź, czy każdy poza ostatnim posiada
komendę „dalej” oraz każdy poza pierwszym komendę „wstecz”.

UWAGA : Na laboratorium 1 interfejs trzeba stworzyć samodzielnie, nie może być „wyklikany” w
Netbeans'ie. Na kolejnych laboratoriach to ograniczenie nie obowiązuje.


Wyszukiwarka

Podobne podstrony:

więcej podobnych podstron