SlideShare ist ein Scribd-Unternehmen logo
1 von 43
Android Development

...and the daily challenges




Dominik Helleberg
inovex GmbH



      Wir nutzen Technologien, um unsere Kunden glücklich zu machen. Und uns selbst.
Intro


Dominik Helleberg
       • Mobile
       • Android
       • HTML5




       • http://twitter.com/_cirrus_
       • http://dominik-helleberg.de/+



10.02.2012                               2
Agenda


• Intro
• Leben in der richtigen Reihenfolge: Lifecycle
• Dispatch it: Asynchrone Aufgaben
• ListViews
• Build it up-to-date: Fragments / ActionBar / User Interface
• Understanding compat mode
• Useful Tools




10.02.2012                                                      3
Activity Lifecycle




10.02.2012           4
Activity Lifecycle Testen


     Device / Emulator rotieren
     Prozess Limit auf 1 setzen
     JUnit test schreiben


public void testLifeCycle()
{
          mActivity = getActivity();

             Instrumentation mInstrumentation = getInstrumentation();
             mInstrumentation.callActivityOnPause(mActivity);
             mInstrumentation.callActivityOnStop(mActivity);
             mInstrumentation.callActivityOnDestroy(mActivity);

             Log.v(TAG, "test done!");
}




10.02.2012                                                              5
Dispatch it: Asynchrone Aufgaben


Aufgabe:


Die App soll die letzte News von Spiegel Online
anzeigen.




10.02.2012                                        6
Dispatch it: Asynchrone Aufgaben


private void fetchSpiegelHeadline()
{
            final String headline = "Eurokrise!";

             URL url = new URL("http://www.spiegel.de");
             URLConnection connection = url.openConnection();
             connection.connect();

             //extract Headline
             Thread.sleep(15000);

             TextView tv = (TextView) findViewById(R.id.async_spiegel_headline);
             tv.setText(headline);
}




10.02.2012                                                                         7
Dispatch it: Asynchrone Aufgaben


@Override
protected void onStart() {
           super.onStart();
           fetchSpiegelHeadline();
}


Was passiert dann?

a) Die Activity wird angezeigt, nach ca. 15 Sekunden wird die Headline
dargestellt
b) Die Activity wird angzeigt, es folgt ein ANR
c) Abhängig vom API Level des Zielgeräts fliegt eine Exception oder es
folgt ein ANR
d) Die Activity wird nicht vollständig angezeigt, es folgt ein ANR



10.02.2012                                                               8
Dispatch it: Asynchrone Aufgaben


@Override
protected void onStart() {
           super.onStart();
           fetchSpiegelHeadline();
}


Was passiert dann?

a) Die Activity wird angezeigt, nach ca. 15 Sekunden wird die Headline
dargestellt
b) Die Activity wird angzeigt, es folgt ein ANR
c) Abhängig vom API Level des Zielgeräts fliegt eine Exception oder
es folgt ein ANR
d) Die Activity wird nicht vollständig angezeigt, es folgt ein ANR



10.02.2012                                                               9
Dispatch it: Asynchrone Aufgaben


     Problem:
             Lang andauernde Operationen:
                Netzwerk
                File I/O
                Preferences
                Datenbankzugriffe


             Android definiert 2 Regeln:
              Do not block the UI thread
              Do not access the Android UI toolkit from outside the UI thread

http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html


10.02.2012                                                                          10
Dispatch it: Asynchrone Aufgaben


Variante 1: Threads


private void useThread() {

             Thread thread = new Thread(new Runnable() {

                       @Override
                       public void run() {
                                fetchSpiegelHeadline();
                       }
             });
             thread.start();
}




10.02.2012                                                 11
Dispatch it: Asynchrone Aufgaben


Variante 1: Threads

private void fetchSpiegelHeadline()
{
            final String headline = "Eurokrise!";

             URL url = new URL("http://www.spiegel.de");
             URLConnection connection = url.openConnection();
             connection.connect();

             //extract Headline
             Thread.sleep(15000);

             TextView tv = (TextView) findViewById(R.id.async_spiegel_headline);
             tv.setText(headline);
}




10.02.2012                                                                         12
Dispatch it: Asynchrone Aufgaben


Variante 1: Threads


Was passiert dann?

a) Die Activity wird angezeigt, nach ca. 15 Sekunden wird die
Headline dargestellt
b) Die Activity wird nicht angezeigt, es folgt ein ANR
c) Die Activity wird angzeigt, es folgt ein ANR
d) Die Activity wird angezeigt, nach ca. 15 Sekunden fliegt eine
Exception




10.02.2012                                                         13
Dispatch it: Asynchrone Aufgaben


Variante 1: Threads


Was passiert dann?

a) Die Activity wird angezeigt, nach ca. 15 Sekunden wird die
Headline dargestellt
b) Die Activity wird nicht angezeigt, es folgt ein ANR
c) Die Activity wird angzeigt, es folgt ein ANR
d) Die Activity wird angezeigt, nach ca. 15 Sekunden fliegt
eine Exception




10.02.2012                                                      14
Dispatch it: Asynchrone Aufgaben


Variante 1: Threads FIXED
private void fetchSpiegelHeadline()
{
            final String headline = "Eurokrise!";

             URL url = new URL("http://www.spiegel.de");
             URLConnection connection = url.openConnection();
             connection.connect();
             //extract Headline
             Thread.sleep(15000);

             runOnUiThread(new Runnable() {
                       @Override
                       public void run() {
                                   TextView tv = (TextView)
                                               findViewById(R.id.async_spiegel_headline);
                                   tv.setText(headline);
                                   }
                       });
}
10.02.2012                                                                                  15
Dispatch it: Asynchrone Aufgaben


Variante 2: AsyncTask

class HeadLineAsyncTask extends AsyncTask<Void, Void, String>
{
             @Override
             protected String doInBackground(Void... params) {

                         final String headline = “Eurokrise!";
                         URL url = new URL("http://www.spiegel.de");
URLConnection connection = url.openConnection();
                         connection.connect();
                         /extract Headline
                         Thread.sleep(15000);
                         return headline;
           }
           @Override
           protected void onPostExecute(String result) {
                         super.onPostExecute(result);
                         TextView tv = (TextView) findViewById(R.id.async_spiegel_headline);
                         tv.setText(result);
           }
}


10.02.2012                                                                                     16
Dispatch it: Asynchrone Aufgaben


Variante 2: AsyncTask

private void useAsyncTask() {
           HeadLineAsyncTask asyncTask = new HeadLineAsyncTask();
           asyncTask.execute();
}




10.02.2012                                                          17
Dispatch it: Asynchrone Aufgaben


Variante 3: Intent Service

private void useIntentService()
{
           startService(new Intent(this, SampleIntentService.class));
}




10.02.2012                                                              18
Dispatch it: Asynchrone Aufgaben


Variante 3: Intent Service

@Override
protected void onStop() {
          super.onStop();
          LocalBroadcastManager.getInstance(this)
                    .unregisterReceiver(mReciever);
}
@Override
protected void onStart() {
          super.onStart();
             LocalBroadcastManager.getInstance(this)
             .registerReceiver(mReciever, new
             IntentFilter(SampleIntentService.INTENT_FILTER_HEADLINE));
}



10.02.2012                                                                19
Dispatch it: Asynchrone Aufgaben


Variante 3: Intent Service

class HeadlineReceiver extends BroadcastReceiver
{
           @Override
           public void onReceive(Context context, Intent intent) {
                       //extract Headline
                       final String headline =
           intent.getExtras().getString(SampleIntentService.EXTRA_HEADLINE);

                     runOnUiThread(new Runnable() {
                               @Override
                               public void run() {
                                           TextView tv = (TextView)
                                           findViewById(R.id.async_spiegel_headline);
                                           tv.setText(headline);
                               }
                     });
             }
}
10.02.2012                                                                              20
Dispatch it: Asynchrone Aufgaben


Variante 4: Loader

private void useLoader() {
            getLoaderManager().initLoader(0, null, this);
}


@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
           return new HeadLinerLoader(this);
}

@Override
public void onLoadFinished(Loader<String> loader, String result) {
            TextView tv = (TextView) findViewById(R.id.async_spiegel_headline);
            tv.setText(result);
}




10.02.2012                                                                        21
Dispatch it: Asynchrone Aufgaben - Übersicht

 Variante    Pros              Cons                 Kommentare            API
                                                                          Level
 Plain       Volle Kontrolle   Kontextgebunden     AsyncTask ist          1
 Threads                       Manuelle UI-Updates meistens besser
                               Hohes
                               Fehlerpotential
 AsyncTask   UI-Updates        Kontextgebunden      ggf. 3rd party Libs   3
             Einfache                               verwenden
             Implementierung
             Einfache
             Callbacks
 Services    Eigener Kontext   Synchronisierung /   Intent Service        3
                               Queue-Kontrolle      meist einfacher
                               Komplizierte
                               Callbacks
 Loader      Eigener Kontext   Vorgegebener                               11 / 4
                               Lifecycle
                               Wenig
10.02.2012
                               Dokumentation                                       22
ListViews


     Universell einsetzbar
     Lösen viele „klassische“ UI-
     Elemente ab (Menus, Tree Views)
     Einfach zu bedienen
     Einfach zu implementieren?




10.02.2012                             23
ListViews – The Framework


     View Recycling
             Android recycelt Views
             Daten müssen von Views getrennt werden


     Performance
             Views so „günstig“ wie möglich erzeugen / füllen
             ViewHolder Pattern




10.02.2012                                                      24
ListViews – View Recycling


     View Recycling
             Android recycelt Views
             Daten müssen von Views getrennt
             werden!!




10.02.2012                                     25
ListViews – View Holder


View Holder – Klasse um recycelte Views schnell füllen zu können
@Override
public View getView(int position, View convertView, ViewGroup parent) {
           View v = convertView;
           if(v == null)
           {
                         v = mLayoutInflater.inflate(R.layout.sequence_list_item, null);
                         ViewHolder vh = new ViewHolder();
                         vh.pb = (SeekBar) v.findViewById(R.id.SequenceSeekBar01);
                         vh.tb = (ToggleButton)
                                     v.findViewById(R.id.SequenceToggleButton01);
                         v.setTag(vh);
           }
           ViewHolder vh = (ViewHolder) v.getTag();
           vh.tb.setChecked( // set Data
           vh.pb.setProgress(//set Data
           return v;
}
class ViewHolder { SeekBar pb; ToggleButton tb;              }


10.02.2012                                                                                 26
Build it up-to-date




     Fragments
     ActionBar
     User Interface / Interaction Design
10.02.2012                                 27
Build it up-to-date – Fragments




     Komponenten mit eigenem Lifecycle
     Benötigen eine Activity
     Eine Activity kann 1 – x Fragments enthalten

10.02.2012                                          28
Build it up-to-date – Fragments


  Kommunikation mit der Activity und anderen Fragments über
        Interfaces
             Activity implementiert MySpecialInterface
        Referenzen
             Fragments halten Referenzen auf andere Fragmente
        Intents
             Activity überschreibt public void startActivity(Intent i) und delegiert die
             Intents ggf. weiteriund tent)




10.02.2012                                                                                 29
Build it up-to-date – ActionBar


     Ersetzt den „TitleBar“
     Ersetzt das klassische „Options Menu“
     Versucht das „Aus den Augen aus dem Sinn“ Problem zu lösen
     Priorisiert die möglichen / sinnvollen Aktionen
     Ergänzt die klassische „Back“ – Navigation
     Wird auch auf Android 2.x schon von vielen populären Apps
     eingesetzt




10.02.2012                                                        30
Build it up-to-date – ActionBar




   • App Icon oder Logo
   • „In-App“ Navigation (optional)




10.02.2012                            31
Build it up-to-date – ActionBar




   • „View Details“
             – Titel
             – In-View Navigation
             – Filter / Drop Downs


10.02.2012                           32
Build it up-to-date – ActionBar




   Actions
             –   Häufigste Aktionen als Icon
             –   Unwichtige Aktionen im Overflow Menu
             –   Texteingabe
             –   Statusanzeige

10.02.2012                                              33
Build it up-to-date – ActionBar


Konvertierungen

     – Options Menu -> Actions

     – Tabbed Activity -> NavigationBar

     – TitleBar -> ActionBar

     – MenuKey ->




 10.02.2012                               34
Build it up-to-date – ActionBar


ActionBarSherlock

• Erweiterung der Google compatibility library
• Ermöglicht die Darstellung von ActionBars
  ab Android 1.6


• Nicht voll 3.x / 4.x API kompatibel



• http://actionbarsherlock.com




 10.02.2012                                      35
User Interface / Interaction Design




10.02.2012                            36
User Interface / Interaction Design


Die wichtigsten News:


     Menu Key ist deprecated
     Kontextmenu ist deprecated
     Long Press ist jetzt „selektieren“
     Neue Gesten (horizontal swipe)




10.02.2012                                37
Understanding compat mode




Target          Max
   Sdk          Sdk


           10           11-13   14
   10.02.2012                        38
Understanding compat mode




Target                         Max
   Sdk                         Sdk


         10           11-13   14
 10.02.2012                          39
Understanding compat mode




                             Target        Max
                                Sdk        Sdk


        10           11-13            14
10.02.2012                                       40
Useful Tools

     Strict Mode - Since API Level 9 – Hift unfreiwillige

public void onCreate() {
               if (DEVELOPER_MODE) {
                   StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                         .detectDiskReads()
                         .detectDiskWrites()
                         .detectNetwork()
                         .penaltyLog()
                         .build());
                   StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                         .detectLeakedSqlLiteObjects()
                         .detectLeakedClosableObjects()
                         .penaltyLog()
                         .penaltyDeath()
                         .build());
               }
               super.onCreate();
}



10.02.2012                                                                            41
Useful Tools

     Hierarchyviewer – Stand Alone Tool im SDK
     Hilft Layout Fehler und performance Probleme zu finden




10.02.2012                                                    42
DANKE!




DANKE!




10.02.2012   43

Weitere ähnliche Inhalte

Ähnlich wie Android Development ...and the daily challenges

Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeFrank Müller
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPAmh0708
 
SOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeSOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeMario Rodler
 
Hands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und StolperfallenHands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und Stolperfalleninovex GmbH
 
.NET Summit 2016 in München: ASP.NET Core 1
.NET Summit 2016 in München: ASP.NET Core 1.NET Summit 2016 in München: ASP.NET Core 1
.NET Summit 2016 in München: ASP.NET Core 1Manfred Steyer
 
BASTA! 2017 Jubiläumskonferenz - Warum warten auf die IDE!?
BASTA! 2017 Jubiläumskonferenz - Warum warten auf die IDE!?BASTA! 2017 Jubiläumskonferenz - Warum warten auf die IDE!?
BASTA! 2017 Jubiläumskonferenz - Warum warten auf die IDE!?Robin Sedlaczek
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit RustJens Siebert
 
Migrationspfade für Angular 2
Migrationspfade für Angular 2Migrationspfade für Angular 2
Migrationspfade für Angular 2Manfred Steyer
 
Automatisierung von Windows-Anwendungen
Automatisierung von Windows-AnwendungenAutomatisierung von Windows-Anwendungen
Automatisierung von Windows-AnwendungenAndreas Schreiber
 
Einführung in den EventBus
Einführung in den EventBusEinführung in den EventBus
Einführung in den EventBustutego
 
Wie skaliert man Software as a Service Applikationen in der Windows Azure Cloud
Wie skaliert man Software as a Service Applikationen in der Windows Azure CloudWie skaliert man Software as a Service Applikationen in der Windows Azure Cloud
Wie skaliert man Software as a Service Applikationen in der Windows Azure CloudPatric Boscolo
 
Ionic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf SteroidenIonic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf SteroidenHendrik Lösch
 
Camunda@1&1
Camunda@1&1Camunda@1&1
Camunda@1&11&1
 

Ähnlich wie Android Development ...and the daily challenges (20)

Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare Systeme
 
Einsteiger Workshop
Einsteiger WorkshopEinsteiger Workshop
Einsteiger Workshop
 
MVVM Pattern
MVVM Pattern MVVM Pattern
MVVM Pattern
 
Lightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPALightweight AOP with CDI and JPA
Lightweight AOP with CDI and JPA
 
Was ist neu in .NET 4.5?
Was ist neu in .NET 4.5?Was ist neu in .NET 4.5?
Was ist neu in .NET 4.5?
 
SOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeSOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter Systeme
 
Hands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und StolperfallenHands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und Stolperfallen
 
Angular2
Angular2Angular2
Angular2
 
Ionic 3
Ionic 3Ionic 3
Ionic 3
 
.NET Summit 2016 in München: ASP.NET Core 1
.NET Summit 2016 in München: ASP.NET Core 1.NET Summit 2016 in München: ASP.NET Core 1
.NET Summit 2016 in München: ASP.NET Core 1
 
BASTA! 2017 Jubiläumskonferenz - Warum warten auf die IDE!?
BASTA! 2017 Jubiläumskonferenz - Warum warten auf die IDE!?BASTA! 2017 Jubiläumskonferenz - Warum warten auf die IDE!?
BASTA! 2017 Jubiläumskonferenz - Warum warten auf die IDE!?
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
Feature Flags mit Togglz
Feature Flags mit TogglzFeature Flags mit Togglz
Feature Flags mit Togglz
 
Migrationspfade für Angular 2
Migrationspfade für Angular 2Migrationspfade für Angular 2
Migrationspfade für Angular 2
 
Automatisierung von Windows-Anwendungen
Automatisierung von Windows-AnwendungenAutomatisierung von Windows-Anwendungen
Automatisierung von Windows-Anwendungen
 
Ruby on Rails SS09 05
Ruby on Rails SS09 05Ruby on Rails SS09 05
Ruby on Rails SS09 05
 
Einführung in den EventBus
Einführung in den EventBusEinführung in den EventBus
Einführung in den EventBus
 
Wie skaliert man Software as a Service Applikationen in der Windows Azure Cloud
Wie skaliert man Software as a Service Applikationen in der Windows Azure CloudWie skaliert man Software as a Service Applikationen in der Windows Azure Cloud
Wie skaliert man Software as a Service Applikationen in der Windows Azure Cloud
 
Ionic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf SteroidenIonic 2 - Hybridapps auf Steroiden
Ionic 2 - Hybridapps auf Steroiden
 
Camunda@1&1
Camunda@1&1Camunda@1&1
Camunda@1&1
 

Mehr von Dominik Helleberg

Mehr von Dominik Helleberg (17)

Why do we need more nerds?
Why do we need more nerds?Why do we need more nerds?
Why do we need more nerds?
 
Android Studio und gradle
Android Studio und gradleAndroid Studio und gradle
Android Studio und gradle
 
Android Studio vs. ADT
Android Studio vs. ADTAndroid Studio vs. ADT
Android Studio vs. ADT
 
Embedded Android
Embedded AndroidEmbedded Android
Embedded Android
 
Supercharge your ui
Supercharge your uiSupercharge your ui
Supercharge your ui
 
Core Android
Core AndroidCore Android
Core Android
 
Android Development Tools
Android Development ToolsAndroid Development Tools
Android Development Tools
 
Android Development Tools
Android Development ToolsAndroid Development Tools
Android Development Tools
 
One APK to rule them all
One APK to rule them allOne APK to rule them all
One APK to rule them all
 
Android ActionBar Navigation reloaded
Android ActionBar Navigation reloadedAndroid ActionBar Navigation reloaded
Android ActionBar Navigation reloaded
 
Rich Graphics & OpenGL mit Android
Rich Graphics & OpenGL mit AndroidRich Graphics & OpenGL mit Android
Rich Graphics & OpenGL mit Android
 
Android Enterprise Integration
Android Enterprise IntegrationAndroid Enterprise Integration
Android Enterprise Integration
 
Android Ice Cream Sandwich WJAX 2011
Android Ice Cream Sandwich WJAX 2011Android Ice Cream Sandwich WJAX 2011
Android Ice Cream Sandwich WJAX 2011
 
Renderscript in Android 3.x
Renderscript in Android 3.xRenderscript in Android 3.x
Renderscript in Android 3.x
 
Dominik Helleberg Widgets Wjax
Dominik Helleberg Widgets WjaxDominik Helleberg Widgets Wjax
Dominik Helleberg Widgets Wjax
 
Widget Workshop Advanced Development
Widget Workshop Advanced DevelopmentWidget Workshop Advanced Development
Widget Workshop Advanced Development
 
Widget Workshop Basics
Widget Workshop BasicsWidget Workshop Basics
Widget Workshop Basics
 

Android Development ...and the daily challenges

  • 1. Android Development ...and the daily challenges Dominik Helleberg inovex GmbH Wir nutzen Technologien, um unsere Kunden glücklich zu machen. Und uns selbst.
  • 2. Intro Dominik Helleberg • Mobile • Android • HTML5 • http://twitter.com/_cirrus_ • http://dominik-helleberg.de/+ 10.02.2012 2
  • 3. Agenda • Intro • Leben in der richtigen Reihenfolge: Lifecycle • Dispatch it: Asynchrone Aufgaben • ListViews • Build it up-to-date: Fragments / ActionBar / User Interface • Understanding compat mode • Useful Tools 10.02.2012 3
  • 5. Activity Lifecycle Testen Device / Emulator rotieren Prozess Limit auf 1 setzen JUnit test schreiben public void testLifeCycle() { mActivity = getActivity(); Instrumentation mInstrumentation = getInstrumentation(); mInstrumentation.callActivityOnPause(mActivity); mInstrumentation.callActivityOnStop(mActivity); mInstrumentation.callActivityOnDestroy(mActivity); Log.v(TAG, "test done!"); } 10.02.2012 5
  • 6. Dispatch it: Asynchrone Aufgaben Aufgabe: Die App soll die letzte News von Spiegel Online anzeigen. 10.02.2012 6
  • 7. Dispatch it: Asynchrone Aufgaben private void fetchSpiegelHeadline() { final String headline = "Eurokrise!"; URL url = new URL("http://www.spiegel.de"); URLConnection connection = url.openConnection(); connection.connect(); //extract Headline Thread.sleep(15000); TextView tv = (TextView) findViewById(R.id.async_spiegel_headline); tv.setText(headline); } 10.02.2012 7
  • 8. Dispatch it: Asynchrone Aufgaben @Override protected void onStart() { super.onStart(); fetchSpiegelHeadline(); } Was passiert dann? a) Die Activity wird angezeigt, nach ca. 15 Sekunden wird die Headline dargestellt b) Die Activity wird angzeigt, es folgt ein ANR c) Abhängig vom API Level des Zielgeräts fliegt eine Exception oder es folgt ein ANR d) Die Activity wird nicht vollständig angezeigt, es folgt ein ANR 10.02.2012 8
  • 9. Dispatch it: Asynchrone Aufgaben @Override protected void onStart() { super.onStart(); fetchSpiegelHeadline(); } Was passiert dann? a) Die Activity wird angezeigt, nach ca. 15 Sekunden wird die Headline dargestellt b) Die Activity wird angzeigt, es folgt ein ANR c) Abhängig vom API Level des Zielgeräts fliegt eine Exception oder es folgt ein ANR d) Die Activity wird nicht vollständig angezeigt, es folgt ein ANR 10.02.2012 9
  • 10. Dispatch it: Asynchrone Aufgaben Problem: Lang andauernde Operationen: Netzwerk File I/O Preferences Datenbankzugriffe Android definiert 2 Regeln: Do not block the UI thread Do not access the Android UI toolkit from outside the UI thread http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html 10.02.2012 10
  • 11. Dispatch it: Asynchrone Aufgaben Variante 1: Threads private void useThread() { Thread thread = new Thread(new Runnable() { @Override public void run() { fetchSpiegelHeadline(); } }); thread.start(); } 10.02.2012 11
  • 12. Dispatch it: Asynchrone Aufgaben Variante 1: Threads private void fetchSpiegelHeadline() { final String headline = "Eurokrise!"; URL url = new URL("http://www.spiegel.de"); URLConnection connection = url.openConnection(); connection.connect(); //extract Headline Thread.sleep(15000); TextView tv = (TextView) findViewById(R.id.async_spiegel_headline); tv.setText(headline); } 10.02.2012 12
  • 13. Dispatch it: Asynchrone Aufgaben Variante 1: Threads Was passiert dann? a) Die Activity wird angezeigt, nach ca. 15 Sekunden wird die Headline dargestellt b) Die Activity wird nicht angezeigt, es folgt ein ANR c) Die Activity wird angzeigt, es folgt ein ANR d) Die Activity wird angezeigt, nach ca. 15 Sekunden fliegt eine Exception 10.02.2012 13
  • 14. Dispatch it: Asynchrone Aufgaben Variante 1: Threads Was passiert dann? a) Die Activity wird angezeigt, nach ca. 15 Sekunden wird die Headline dargestellt b) Die Activity wird nicht angezeigt, es folgt ein ANR c) Die Activity wird angzeigt, es folgt ein ANR d) Die Activity wird angezeigt, nach ca. 15 Sekunden fliegt eine Exception 10.02.2012 14
  • 15. Dispatch it: Asynchrone Aufgaben Variante 1: Threads FIXED private void fetchSpiegelHeadline() { final String headline = "Eurokrise!"; URL url = new URL("http://www.spiegel.de"); URLConnection connection = url.openConnection(); connection.connect(); //extract Headline Thread.sleep(15000); runOnUiThread(new Runnable() { @Override public void run() { TextView tv = (TextView) findViewById(R.id.async_spiegel_headline); tv.setText(headline); } }); } 10.02.2012 15
  • 16. Dispatch it: Asynchrone Aufgaben Variante 2: AsyncTask class HeadLineAsyncTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... params) { final String headline = “Eurokrise!"; URL url = new URL("http://www.spiegel.de"); URLConnection connection = url.openConnection(); connection.connect(); /extract Headline Thread.sleep(15000); return headline; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); TextView tv = (TextView) findViewById(R.id.async_spiegel_headline); tv.setText(result); } } 10.02.2012 16
  • 17. Dispatch it: Asynchrone Aufgaben Variante 2: AsyncTask private void useAsyncTask() { HeadLineAsyncTask asyncTask = new HeadLineAsyncTask(); asyncTask.execute(); } 10.02.2012 17
  • 18. Dispatch it: Asynchrone Aufgaben Variante 3: Intent Service private void useIntentService() { startService(new Intent(this, SampleIntentService.class)); } 10.02.2012 18
  • 19. Dispatch it: Asynchrone Aufgaben Variante 3: Intent Service @Override protected void onStop() { super.onStop(); LocalBroadcastManager.getInstance(this) .unregisterReceiver(mReciever); } @Override protected void onStart() { super.onStart(); LocalBroadcastManager.getInstance(this) .registerReceiver(mReciever, new IntentFilter(SampleIntentService.INTENT_FILTER_HEADLINE)); } 10.02.2012 19
  • 20. Dispatch it: Asynchrone Aufgaben Variante 3: Intent Service class HeadlineReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //extract Headline final String headline = intent.getExtras().getString(SampleIntentService.EXTRA_HEADLINE); runOnUiThread(new Runnable() { @Override public void run() { TextView tv = (TextView) findViewById(R.id.async_spiegel_headline); tv.setText(headline); } }); } } 10.02.2012 20
  • 21. Dispatch it: Asynchrone Aufgaben Variante 4: Loader private void useLoader() { getLoaderManager().initLoader(0, null, this); } @Override public Loader<String> onCreateLoader(int id, Bundle args) { return new HeadLinerLoader(this); } @Override public void onLoadFinished(Loader<String> loader, String result) { TextView tv = (TextView) findViewById(R.id.async_spiegel_headline); tv.setText(result); } 10.02.2012 21
  • 22. Dispatch it: Asynchrone Aufgaben - Übersicht Variante Pros Cons Kommentare API Level Plain Volle Kontrolle Kontextgebunden AsyncTask ist 1 Threads Manuelle UI-Updates meistens besser Hohes Fehlerpotential AsyncTask UI-Updates Kontextgebunden ggf. 3rd party Libs 3 Einfache verwenden Implementierung Einfache Callbacks Services Eigener Kontext Synchronisierung / Intent Service 3 Queue-Kontrolle meist einfacher Komplizierte Callbacks Loader Eigener Kontext Vorgegebener 11 / 4 Lifecycle Wenig 10.02.2012 Dokumentation 22
  • 23. ListViews Universell einsetzbar Lösen viele „klassische“ UI- Elemente ab (Menus, Tree Views) Einfach zu bedienen Einfach zu implementieren? 10.02.2012 23
  • 24. ListViews – The Framework View Recycling Android recycelt Views Daten müssen von Views getrennt werden Performance Views so „günstig“ wie möglich erzeugen / füllen ViewHolder Pattern 10.02.2012 24
  • 25. ListViews – View Recycling View Recycling Android recycelt Views Daten müssen von Views getrennt werden!! 10.02.2012 25
  • 26. ListViews – View Holder View Holder – Klasse um recycelte Views schnell füllen zu können @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if(v == null) { v = mLayoutInflater.inflate(R.layout.sequence_list_item, null); ViewHolder vh = new ViewHolder(); vh.pb = (SeekBar) v.findViewById(R.id.SequenceSeekBar01); vh.tb = (ToggleButton) v.findViewById(R.id.SequenceToggleButton01); v.setTag(vh); } ViewHolder vh = (ViewHolder) v.getTag(); vh.tb.setChecked( // set Data vh.pb.setProgress(//set Data return v; } class ViewHolder { SeekBar pb; ToggleButton tb; } 10.02.2012 26
  • 27. Build it up-to-date Fragments ActionBar User Interface / Interaction Design 10.02.2012 27
  • 28. Build it up-to-date – Fragments Komponenten mit eigenem Lifecycle Benötigen eine Activity Eine Activity kann 1 – x Fragments enthalten 10.02.2012 28
  • 29. Build it up-to-date – Fragments Kommunikation mit der Activity und anderen Fragments über Interfaces Activity implementiert MySpecialInterface Referenzen Fragments halten Referenzen auf andere Fragmente Intents Activity überschreibt public void startActivity(Intent i) und delegiert die Intents ggf. weiteriund tent) 10.02.2012 29
  • 30. Build it up-to-date – ActionBar Ersetzt den „TitleBar“ Ersetzt das klassische „Options Menu“ Versucht das „Aus den Augen aus dem Sinn“ Problem zu lösen Priorisiert die möglichen / sinnvollen Aktionen Ergänzt die klassische „Back“ – Navigation Wird auch auf Android 2.x schon von vielen populären Apps eingesetzt 10.02.2012 30
  • 31. Build it up-to-date – ActionBar • App Icon oder Logo • „In-App“ Navigation (optional) 10.02.2012 31
  • 32. Build it up-to-date – ActionBar • „View Details“ – Titel – In-View Navigation – Filter / Drop Downs 10.02.2012 32
  • 33. Build it up-to-date – ActionBar Actions – Häufigste Aktionen als Icon – Unwichtige Aktionen im Overflow Menu – Texteingabe – Statusanzeige 10.02.2012 33
  • 34. Build it up-to-date – ActionBar Konvertierungen – Options Menu -> Actions – Tabbed Activity -> NavigationBar – TitleBar -> ActionBar – MenuKey -> 10.02.2012 34
  • 35. Build it up-to-date – ActionBar ActionBarSherlock • Erweiterung der Google compatibility library • Ermöglicht die Darstellung von ActionBars ab Android 1.6 • Nicht voll 3.x / 4.x API kompatibel • http://actionbarsherlock.com 10.02.2012 35
  • 36. User Interface / Interaction Design 10.02.2012 36
  • 37. User Interface / Interaction Design Die wichtigsten News: Menu Key ist deprecated Kontextmenu ist deprecated Long Press ist jetzt „selektieren“ Neue Gesten (horizontal swipe) 10.02.2012 37
  • 38. Understanding compat mode Target Max Sdk Sdk 10 11-13 14 10.02.2012 38
  • 39. Understanding compat mode Target Max Sdk Sdk 10 11-13 14 10.02.2012 39
  • 40. Understanding compat mode Target Max Sdk Sdk 10 11-13 14 10.02.2012 40
  • 41. Useful Tools Strict Mode - Since API Level 9 – Hift unfreiwillige public void onCreate() { if (DEVELOPER_MODE) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build()); } super.onCreate(); } 10.02.2012 41
  • 42. Useful Tools Hierarchyviewer – Stand Alone Tool im SDK Hilft Layout Fehler und performance Probleme zu finden 10.02.2012 42