Szybciej (pisać) Łatwiej (czytać) Prościej (utrzymywać) Marcin Wąsowski Amsterdam Standard Sp. z o.o.

Podobne dokumenty
Systemy operacyjne na platformach mobilnych

akademia androida Http i AsyncTask część VII

Fragmenty są wspierane od Androida 1.6

akademia androida Service, BroadcastReceiver, ContentProvider część IV

Mechanizm powiadomień

Powiadomienia w systemie Android

Programowanie urządzeń mobilnych. dr inż. Andrzej Grosser na podstawie wykładu dr inż. Juliusza Mikody

AndroidManifest.xml. Plik manifestu opisuje podstawowe charakterystyki aplikacji i definiuje jej komponenty.

Android pierwsza aplikacja

Programowanie urządzeń mobilnych. dr inż. Juliusz Mikoda

Laboratorium Systemów Mobilnych. Wykład 1

BEAN VALIDATION. Waldemar Korłub. Narzędzia i aplikacje Java EE KASK ETI Politechnika Gdańska

Aktywności są związane z ekranem i definiują jego wygląd. Dzieje się to poprzez podpięcie do aktywności odpowiedniego widoku.

Mechanizm zapisu preferencji

Tłumaczenie i adaptacja materiałów: dr Tomasz Xięski. Na podstawie prezentacji udostępnionych przez Victor Matos, Cleveland State University.

[Android] Podstawy programowania

Laboratorium Systemów Mobilnych. Wykład 2

Systemy operacyjne na platformach mobilnych

Podstawowe elementy GUI - zadania

Systemy operacyjne na platformach mobilnych

AKADEMIA MŁODYCH ODKRYWCÓW

Tworzenie dialogów i wykorzystanie klasy Toast

Programowanie urządzeń mobilnych w systemie Android. Ćwiczenie 7 Wykorzystanie układu LinearLayout

RESTful Android. Na co zwrócić uwagę przy tworzeniu aplikacji klienckich REST na Androidzie

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Android. Zarz dzanie cyklem»ycia i stanem. Piotr Fulma«ski. March 10, 2015

Java: interfejsy i klasy wewnętrzne

Programowanie obiektowe

Obsługa SMS i telefonii

Systemy operacyjne na platformach mobilnych

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

I. Usługi. Usługa może przyjąć dwie formy:

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Programowanie urządzeń mobilnych w systemie Android. Ćwiczenie 8 Wykorzystanie układu RelativeLayout

Programowanie usług działających w tle

akademia androida Składowanie danych część VI

Programowanie urządzeń mobilnych. dr inż. Andrzej Grosser na podstawie wykładu dr inż. Juliusza Mikody

Aplikacje Internetowe. Najprostsza aplikacja. Komponenty Javy. Podstawy języka Java

Programowanie urządzeń mobilnych. dr inż. Andrzej Grosser na podstawie wykładu dr inż. Juliusza Mikody

Programowanie obiektowe

Dlaczego Android? Uczę się Javy więc piszę.. w Androidzie. Nie mam telefonu z Androidem!

Polimorfizm. dr Jarosław Skaruz

Wykorzystanie plików

Agenda. Bazy danych SQLite Zestawienie mapowania w LiteORM Wyświetlanie danych w ListView

grafika 2D i animacja obsługa rotacji i elementy 3D-OpenGL w Androidzie

Życie aktywności Nawigując przez aplikacje poszczególne Aktywności przechodzą pomiędzy stanami. Dla przykładu gdy aktywność uruchamia się po raz

Generatory. Michał R. Przybyłek

Podstawowe elementy GUI - zadania

akademia androida Intencje oraz URI część III

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

public enum Environment { Development("Deweloperskie"), Test("Testowe"), Production("Produkcyjne"); private String name;

Wątki. Definiowanie wątków jako klas potomnych Thread. Nadpisanie metody run().

1 LINQ. Zaawansowane programowanie internetowe Instrukcja nr 1

Automatyczne testowanie aplikacji Android

Programowanie obiektowe

Instrukcja implementacji sterownika wirtualnego portu szeregowego dla systemu Android. Opracowanie: Elzab Soft sp. z o.o.

Programowanie obiektowe

Budowa prostej aplikacji wielowarstwowej. Laboratorium 1 Programowanie komponentowe Zofia Kruczkiewicz

Tworzenie wydajnych interfejsów. Autorzy: Piotr Michałkiewicz, 2 rok AiR Daniel Maksymow, 2 rok Informatyki

JAX-RS czyli REST w Javie. Adam Kędziora

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

SWING c.d. przydatne narzędzia: JFileChooser, JOptionPane. drag'n drop, menu kontekstowe.

Wyświetlanie danych na listach

Jakarta POI. POIFS obsługa dokumentów OLE 2, HSSF dokumenty w formacie Excel'a, HWPF proste dokumenty w formacie Word 97,

Usługa TimerService

Zastosowanie słuchaczy zdarzeń wg

Tworzenie natywnych aplikacji na urządzenia mobilne - PhoneGap Tomasz Margalski

Języki Programowania II Wykład 3. Java podstawy. Przypomnienie

Android, wprowadzenie do SDK

Programowanie obiektowe

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Wzorce prezentacji internetowych

Ekspert radzi. mechanizm w enova, umożliwiający wskazanie domyślnej drukarki dla danego stanowiska i wydruku. Strona 1 z 8. Ekspert radzi.

Budowa aplikacji wielowarstwowych zastosowanie szablonów. Laboratorium 2 Programowanie komponentowe Zofia Kruczkiewicz

Platformy Programistyczne Podstawy języka Java

Tworzenie i wykorzystanie usług

ANDROID. OpenGL ES 1.0. Tomasz Dzieniak

Diagram stanów Laboratorium 9

Dokumentacja do API Javy.

Zdarzenia Klasa Application Powiadomienia Toast AlertDialog

Zaawansowane aplikacje WWW - laboratorium

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Programowanie w JAVA Lab. 5 - Wątki. 1. Wykorzystując metodę Monte Carlo narysować wykres funkcji oraz obliczyć całkę: 7 x ) xy, 8,8

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Automaty do zadań specjalnych. Olga Maciaszek-Sharma, Artur Kotow Wersja 1,

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Języki i metody programowania Java. Wykład 2 (część 2)

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Stanowe komponenty sesyjne

JAVA : TELEFONY KOMÓRKOWE I ANDROID 1. WSTĘP

Metody Metody, parametry, zwracanie wartości

Wykorzystanie map i geolokalizacji

Programowanie Urządzeń Mobilnych. Część II: Android. Wykład 2

Wsparcie dla różnych urządzeń. SDK pozwala przystosować aplikację do większości tych wypadków

Programowanie urządzeń mobilnych. dr inż. Andrzej Grosser na podstawie wykładu dr inż. Juliusza Mikody

Komponenty sterowane komunikatami

Java. Programowanie Obiektowe Mateusz Cicheński

Transkrypt:

Szybciej (pisać) Łatwiej (czytać) Prościej (utrzymywać) Marcin Wąsowski Amsterdam Standard Sp. z o.o.

Co dostajemy na starcie? pobieranie elementów widoku, rzutowanie: ( np. findbyid ) każde zdarzenie = nowa klasa listenera ( często anonimowa) skomplikowany model wykonywania zadań w tle rozwlekły dostęp do zasobów, preferencji, serwisów systemowych i jeszcze kilka innych wypełniaczy czasu

Zacznijmy od UI <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/txvname" android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/app_name" /> <ImageView android:id="@+id/ivphoto" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/txvname" android:layout_above="@+id/btnothers" android:contentdescription="@string/example_image" /> <Button android:id="@+id/btnothers" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignparentbottom="true" android:text="@string/others" /> </RelativeLayout>

public class SimpleActivity extends Activity { private TextView txvname; private ImageView ivphoto; private Button btnothers; @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); requestwindowfeature(window.feature_no_title); getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, WindowManager.LayoutParams.FLAG_FULLSCREEN); setcontentview(r.layout.activity_simple); this.txvname = (TextView)findViewById(R.id.txvName); this.ivphoto = (ImageView)findViewById(R.id.ivPhoto); this.btnothers = (Button)findViewById(R.id.btnOthers); this.btnothers.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view sender) { //Logika przejścia do listy } }); this.ivphoto.setonlongclicklistener(new View.OnLongClickListener() { @Override public boolean onlongclick(view arg0) { //Pobranie następnego zdjęcia return false; } }); Spanned phototitlespanned = Html.fromHtml(getString(R.string.photo_title)); this.txvname.settext(phototitlespanned); } }

@Fullscreen @WindowFeature({Window.FEATURE_NO_TITLE}) @EActivity(R.layout.activity_simple) public class AASimpleActivity extends Activity { @ViewById(R.id.txvName) @FromHtml(R.string.photo_title) protected TextView txvname; @Click(R.id.btnOthers) protected void btnothersclick(view sender){ //Logika przejścia do listy } } @LongClick(R.id.ivPhoto) protected void ivphotolongclick(view sender){ //Pobranie następnego zdjęcia }

Jak więc dokonać takiej zmiany? Po kolei: - mamy adnotacje (annotations) - należy je przetworzyć. Jak? : 1. Przetwarzanie w runtime"-ie 2. Przetwarzanie podczas kompilacji. Wolne, narzut w wykonaniu. Wydaje się być ok. - jeśli podejście 2 to należy gdzieś zapisać rezultat. Generator kodu.

AndroidAnnotations Biblioteka ta działa właśnie w zaprezentowany sposób. Wprowadza elementy, które nazywa rozszerzonymi komponentami Obiekt taki deklarujemy poprzez zdefiniowanie dla adnotacji @E.. Mamy dostępne: @EActivity, @EApplication, @EBean, @EFragment, @EProvider, @EReceiver, @EIntentService, @EService, @EView, @EViewGroup, @EProvider, Generowana jest klasa odpowiedzialna za obsłużenie funkcjonalności rozszerzonego komponentu : @EActivity(R.layout.activity_main) public final class MainActivity_ public class MainActivity extends Activity { extends MainActivity implements HasViews, OnViewChangedListener {

Komponenty- subiektywny podział: Wykorzystywane bezpośrednio przez środowisko Androida: @EActivity Actvity @EProvider ContentProvider @EService Service, IntentService @EIntentService IntentService @EReceiver BroadcastReceiver @EProvider ContentProvider Wizualne: @EFragment (?) @EView @EViewGroup Fragment View ViewGroup Wstrzykiwane: @EApplication (?) @Application Application @EBean @Bean Object

Wstrzykiwanie zależności (DI) @AfterInject - po wstrzyknięciu wszystkie zależności. Wykorzystywana w każdym z rodzajów komponentów @AfterViews - po zabindowaniu wszystkich składowych widoku. Wykorzystywana w: @EActivity, @EFragment, @EView, @EViewGroup, @EBean (?)

Pobieranie elementów widoku @AfterViews - wszystkie elementy widoku zabindowane. @ViewById - pobranie elementów widoku //Deklaracje private ImageView ivphoto; private Button btnothers;! //A później w oncreate this.ivphoto = (ImageView)findViewById(R.id.ivPhoto); this.btnothers = (Button)findViewById(R.id.btnOthers); FragmentById oraz @FragmentByTag @ViewById(R.id.btnOthers) protected Button somebutton; @ViewById protected ImageView ivphoto; //Deklaracje... protected ExampleFragment frgexample1; protected ExampleFragment frgtag3; //...a następnie frgexample1 = ((ExampleFragment) getsupportfragmentmanager(). findfragmentbyid(r.id.frgexample1)); frgtag3 = ((ExampleFragment) getsupportfragmentmanager(). findfragmentbytag("frgtag3")); @FragmentById(R.id.frgExample1) protected AAExampleFragment frgexample1; @FragmentByTag("frgTag3") protected AAExampleFragment frgtag3;

Konfiguracja fragmentów i aktywności @Extra Bundle extras = this.getintent().getextras(); this.exampleextra = extras.containskey("exampleextra")? extras.getstring("exampleextra") : "default_value"; @Extra protected String exampleextra = "default_value"; @FragmentArg Bundle args = this.getarguments(); if(args!=null){ this.exampleargument = args.containskey("exampleargument")? args.getstring("exampleargument") : null; } @FragmentArg("exampleArgument") protected String exampleargument; @NonConfigurationInstance

Wstrzykiwanie własnych zasobów @Bean @EBean public class AAMyBean { @EBean(scope=Scope.Singleton) public class AAMySingletonBean { @Bean protected AAMyBean examplebean; @Bean protected AAMySingletonBean examplesingletonbean; @App @EApplication public class AAExampleApplication extends Application { @Override public void oncreate(){ super.oncreate(); this.initializetaskinbg(); } @Background protected void initializetaskinbg(){ //Operacje } } <application android:allowbackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/apptheme" android:name=".aa.aaexampleapplication_"> @App protected AAExampleApplication app;

Wstrzykiwanie zasobów systemowych @RootContext public class AASimpleActivity extends Activity { @Bean protected AAMyBean examplebean; @EBean public class AAMyBean { @RootContext protected Context context; @RootContext protected Activity anyactivitycontext; @RootContext protected AASimpleActivity exactactvitycontext; } @SystemService //Deklaracja... private NotificationManager nmanager; //... i pobranie this.nmanager = (NotificationManager) this.getsystemservice(context.notification_service); @SystemService protected NotificationManager nmanager;

Obsługa zdarzeń Standardowo mamy:! //Deklaracja... private Button btncancel; //... pobranie... this.btncancel = (Button)findViewById(R.id.btnCancel); //... a następnie przypisanie klasy "listenera" this.btncancel.setonclicklistener( new View.OnClickListener() { @Override public void onclick(view v) { //[..] w przypadku AndroidAnnotations: Dostępne zdarzenia: @Click(R.id.btnCancel) protected void btncancelclick(){ //[...] - @Click, @Touch, @LongClick - @SeekBarProgressChange, @SeekBarTouchStart, @SeekBarTouchStop - @ItemClick, @ItemLongClick, @ItemSelect - @OptionsItem - @FocusChanges, @CheckedChange

public class ThreadActivity extends Activity { private TextView txvprogress; private Button btnstart; private Button btncancel; private OperationTask task; @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_thread); this.btncancel = (Button)findViewById(R.id.btnCancel); this.btnstart = (Button)findViewById(R.id.btnStart); this.txvprogress = (TextView)findViewById(R.id.txvProgress); this.btnstart.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { if(task!=null && task.getstatus() == AsyncTask.Status.RUNNING){ task.cancel(true); } task = new OperationTask(); task.execute(100l); } }); this.btncancel.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { if(task!=null && task.getstatus() == Status.RUNNING){ task.cancel(true); } } }); } private void showfinish(string message){ this.txvprogress.settext(message); Toast.makeText(this, message, Toast.LENGTH_LONG).show(); } private void showprogress(string message){ this.txvprogress.settext(message); } private class OperationTask extends AsyncTask<Long, Integer, Long> {/*[...]*/} } Praca z wątkami private class OperationTask extends AsyncTask<Long, Integer, Long> { @Override protected Long doinbackground(long... params) { long time = 0; try{ for(int i = 0; i < 100; i++){ Thread.sleep(params[0]); time += params[0]; publishprogress(i); if (iscancelled()) break; } }catch(interruptedexception e){ return -1L; } return time; } @Override protected void onprogressupdate(integer... values) { showprogress(getstring(r.string.progress, values[0])); } @Override protected void onpostexecute(long result) { showfinish(getstring(r.string.finished, (long)result)); } }

Praca z wątkami (AA) AsyncTask @Background - id - serial - delay @UiThread - delay @EActivity(R.layout.activity_thread) public class AAThreadActivity extends Activity { @ViewById(R.id.txvProgress) protected TextView txvprogress; @Click(R.id.btnStart) protected void btnstartclick(){ dooperation(100); } @Click(R.id.btnCancel) protected void btncancelclick(){ BackgroundExecutor.cancelAll("operation", true); } @Background(id="operation") protected void dooperation(int timestep){ long time = 0; try{ for(int i = 0; i < 100; i++){ Thread.sleep(timeStep); time += timestep; showprogress(getstring(r.string.progress, i)); } }catch(interruptedexception e){ showfinish(getstring(r.string.finished, -1L)); } showfinish(getstring(r.string.finished, time)); } @UiThread protected void showprogress(string message){ this.txvprogress.settext(message); } @UiThread protected void showfinish(string message){ this.txvprogress.settext(message); Toast.makeText(this, message, Toast.LENGTH_LONG).show(); } }

Zasoby Aby skorzystać z jakiegoś zasobu: W przypadku wykorzystania AA: //Deklaracja... private String applicationname; //... i pobranie this.applicationname = getresources(). getstring(r.string.app_name); @StringRes(R.string.app_name) protected String applicationname; Dostępna jest cała rodzina adnotacji @XXXRes: @StringRes, @AnimationRes, @ColorRes, @DimensionPixelOffsetRes, @DimensionPixelSizeRes, @DimensionRes, @BooleanRes, @ColorStateListRes, @DrawableRes, @IntArrayRes, @IntegerRes, @LayoutRes, @MovieRes, @StringArrayRes, @TextArrayRes, @TextRes, @HtmlRes

SharedPreferences Wykorzystanie standardowe: SharedPreferences prefs = this.getsharedpreferences( "pl.amsard.aa3examples", Context.MODE_PRIVATE); prefs.edit().putlong("timekey", new Date().getTime()+3600).commit(); long time = prefs.getlong("timekey", new Date().getTime());! W przypadku użycia AA: @SharedPref public interface AAPrefs { long time(); } long time = prefs.time().getor(new Date().getTime()); this.prefs.edit().time().put(new Date().getTime()+3600).apply(); this.prefs.clear();

Klient RESTowego API Oparty o Spring Android (core, RestTemplate) Dodatkowo wymaga serializera do określonego, używanego formatu danych (np. Jackson - JSON) Jak używać: @Rest(converters = { MappingJacksonHttpMessageConverter.class, FormHttpMessageConverter.class }) public interface WebserviceClientInterface { @Get("/api/news?lang={lang}&api={api}") NewsResponse getnews(string lang, int api); @Post("/api/auth") AuthorizeResponse authorizeuser(userpostparams params); } @RestService protected WebserviceClientInterface restclient;

Jeszcze kilka przydatnych dodatków Integracja z biblioteką RoboGuice Integracja z biblioteką ORMLite

Q&A mail: marcin.wasowski@amsterdam-standard.pl przykłady: http://github.com/marcinwasowski/aa_examples więcej?: Zapraszamy: