SlideShare una empresa de Scribd logo
1 de 19
Descargar para leer sin conexión
A Unified Approach to Callbacks in Android




           Matt Brenner – UnME2, Inc.
               mbrenner@unme2.com

               Droidcon Berlin 2013
Background Knowledge

This talk will include discussion of,
   threads
   Interfaces
   callbacks
   Observer Design Pattern

and make extensive use of UML.

Don't worry, we'll “fill in” all gaps along the way!
A Unified Approach to Callbacks in Android


In Java, callbacks commonly occur within processes:
   between threads
   to decouple domain / interface (e.g. Observer)
“Worker Thread” Callback
public Interface Requester {
          public void complete ( );                               Requester
}                                                                 «interface»

public class Mainclass implements Requester {              + complete( ) : void
          ...
          public void dosomething (...) {
                    ...
                    (new Worker (this)).start ();
          }                                                        Mainclass

         public void complete ( ) {                      + dosomething (...) : void
                   ...                                   + complete( ) : void
         }                                                       ...
}



public class Worker extends Thread {
          private Requester requester_;
                                                                   Thread
          ...
          public Worker (Requester requester) {
                    requester_ = requester
          }
          ...
          public void run( ) {                                     Worker
                    ...
                    requester_.complete ( );        + Worker (requester : Requester)
          }                                         + run ( ) : void
}                                                           ...
“Domain-to-Interface” Callback (Observer Pattern)

                                                                        Observer
public class Widget implements Observer {                              «interface»
          ...
          public Widget (Domainthing thing) {          + update (:Observable, data : Object) : void
                   ...
                   thing.addObserver (this);
          }

          public void update (Observable obs, Object                     Widget
data) {
                  ...                                  + Widget (:Domainthing)
          }                                            + update (:Observable, data : Object) : void
}                                                               ...




public class Domainthing extends Observable {                        Observable
          ...
          private void domainchange (Object data ) {      + addObserver (:Observer) : void
                                                          + setChanged ( ) : void
                    ...
                    setChanged ( );                       + notifyObservers (:Object) : void
                    notifyObservers (data);
          }
}
                                                                      Domainthing
Android Makes Extensive Use Intents

Intents are used:
    for inter-process and inter-Activity comms
   to invoke Activities (passing params)
   to callback from one Activity to another
    (return a result)
Activity Callback
(Calling Activity)
public class AnActiviy extends Activity {
          static private final int              GOTYESNO = 1,
          ...

         public void askyesno( ) {
                   Intent             intent;

                   ...
                   intent = new Intent (this, ActivityGetyesno.class);
                   intent.putExtra (“title”, R.string.delete_all_title);
                   intent.putExtra (“msg”, R.string.delete_all_msg);
                   startActivityForResult (intent, GOTYESNO);
         }


       protected void onActivityResult (int id, int result, Intent data) {
                if (id == GOTYESNO) {
                           if (data.hasExtra (“RESULT”)) {
                                     result = data.getExtras( ).getString
(“RESULT”);
                                     if (result.equals (“yes”)) {
                                                ...
                                     }
                           }
                }
       }
       ...
}
Activity Callback
(Called Activity)
public class ActivityGetyesno extends Activity {
          ...
          protected void onCreate (Bundle bundle) {
                    super.onCreate (bundle);

                    String    title, message;

                    title = message = null;
                    Bundle params = getIntent ( ).getExtras
( );
                    if (params != null) {
                             title = params.getString (“title”);
                             message = params.getString
(“msg”);
                    }
                    ...
           }

           public void clickno (View view) {
                     done (“no”);
           }

           public void clickyes (View view) {
                     done (“yes”);
           }

           private void done (String result) {
                     Intent intent = new Intent ( );
                     intent.putExtra (“RESULT”, result);
                     setResult (Activity.RESULT_OK, intent);
                     finish ( );
           }
A Bit of a Mess

  Multiple callbacks in various forms lead to:

     interface “clutter”
     multiple callback forms in a single class
     Intent syntax is klunky and repetitious


New design pattern to the rescue: Event Consumer (Brenner)
Event Consumer
         Activity



                        SuperActivity «abstract»                                                Eventconsumer
                                                                                                  «interface»
+ event (eventid : int) : void
+ event (eventid : int, data : Object) : void                                      + event (eventid : int) : void
+ event (eventid : int, data : Object, resultcode : int) : void                    + event (eventid : int, data : Object
+ onActivityResult (eventid : int, resultcode : int, intent : Intent) : void
# abort ( ) : void
# done (response : int) : void
# done (response : String) : void
# getparamstring ( ) : String
# getresult ( ) : int
# getresultstring ( ) : String
# isabort ( ) : boolean
# isuccess ( ) : boolean
# isyes ( ) : boolean                                                                               AnActivity

                                                                                + func ( ) : void
                                                                                + event (eventid : int, data : Object) : void
             DialogActivity «abstract»

+ onCreate (bundle: Bundle, layout : int) : void
+ event (eventid : int, data : Object) : void
+ getitlefield ( ) : TextView
+ getmsgfield ( ) : TextView
+ onBackPressed ( ) : void                                             ActivityGetyesnodialog

                                                           + onCreate (bundle : Bundle) : void
                                                           + clickno (View view) : void
                                                           + clickyes (View view) : void
Using the Event Consumer Pattern


Let's see how to use Event Consumer for callbacks:

    from a worker-thread
    from domain to interface
    between Intents
Event Consumer: “Worker Thread” Callback

Old Version (caller)
New Version (caller)                               NewVersion (worker)
                                                   Old Version (worker)

        Interface Requester {
public class Mainclass                              public class Worker extends Thread {
   public void complete ( );
           implements Eventconsumer                            Requester
                                                      private int                       requester_;
                                                                                        eventid_;
}
{                                                     ...
   static private final int     COMPLETE = 1;         privateWorker (Requester requeseter) {
                                                      public Eventconsumer caller_;
public class Mainclass implements Requester {
           ...                                                requester_ = requeseter;
   ...                                                }
                                                      public Worker (Eventconsumer caller, int eventid) {
   public void dosomething (...) {                    ...     caller_ = caller;
           ...
           (new Worker (this, COMPLETE)).start (      public void run( = {eventid;
                                                              eventid_ )
);         (new Worker (this).start ();               }       ...
   }                                                          requester_.complete( );
                                                      }
                                                      public void run ( ) {
  public void complete ( ) {                        }         ...
         ...
  public void event (int eventid, Object data) {              caller_.event (eventid_);
  }      switch (eventid) {                           }
}         case COMPLETE:                            }
             ...
             break;
         }
  }
}
Event Consumer: “Domain-to-Interface” Callback
New Version                                          Old Version
public class Widget                                  Old Version
                                                      public class Widget implements Observer {
  implements Eventconsumer                              ...
                                                      public class Domainthing extends Observable {
{                                                               ...
  static private final int UPDATE = 1;                          private void domainchange (Object data ) {
          ...                                                             ...
                                                        public Widget (Domainthing thing) {
                                                                          setChanged ( );
    public void observe (Domainthing thing) {                   ...
                                                                          notifyObservers (data);
           thing.addobserver (this, UPDATE);                    thing.addObserver (this);
                                                                }
    }                                                   }
                                                      }
    public void event (int eventid, Object data) {        public void update (Observable obs, Object data) {
           switch (eventid) {                                    ...
            case UPDATE:                                  }
              ...
                                                     New Version
                                                      }
              break;                                  public class Domainthing {
           }                                            private int                                eventid_;
    }                                                   private Eventconsumer              observer_;
}                                                               ...

                                                          public void addobserver (Eventconsumer obs, int eventid) {
                                                                 observer_ = obs;
                                                                 eventid_ = eventid;
                                                          }

                                                          private void domainchange (Object data) {
                                                                 ...
                                                                 observer_.event (eventid, data);
                                                          }
                                                      }
Event Consumer: Intent Callback
New Version (Calling Activity)                         Old Version (Calling Activity)
public class AnActiviy extends SuperActivity {         public class AnActiviy extends Activity {
  static private final int          GOTYESNO = 1;        static private final int            GOTYESNO = 1,
          ...                                            ...

   public void askyesno( ) {                             public void askyesno( ) {
          Launcher                       launcher;              Intent               intent;
          ...                                                   ...
          lancher = new Launcher (this, GOTYESNO,               intent = new Intent (this, ActivityGetyesno.class);
              R.string.delete_all_title,                        intent.putExtra (“title”, R.string.delete_all_title);
R.string.delete_all_msg);                                       intent.putExtra (“msg”, R.string.delete_all_msg);
                                                                startActivityForResult (intent, GOTYESNO);
           launcher.launch (ActivityGetyesno.class);            ...
    }                                                    }

                                                          protected void onActivityResult (int id, int result,Intent data)
    public void event (int eventid, Object data) {        {
           switch (eventid) {                                    if (id == GOTYESNO) {
            case GOTYESNO:                                           if (data.hasExtra (“RESULT”)) {
              if (isyes()) {                                                 result = data.getExtras( ).getString
                      ...                              (“RESULT”);
              }                                                              if (result.equals (“yes”)) {
              break;                                                             ...
           }                                                                 }
    }                                                                }
}                                                                }
                                                          }
                                                       }
Event Consumer: Intent Callback
New Version (Called                             Old Version (Called Activity)
Activity) ActivityGetyesno
public class                                    public class ActivityGetyesno extends Activity {
    extends DialogActivity                                ...
{                                                         protected void onCreate (Bundle bundle) {
   public void onCreate (Bundle bundle)     {                       super.onCreate (bundle);
          super.onCreate (bundle,
R.layout.dialog_yesno);                                               String    title, message;
          ...
   }                                                                  title = message = null;
                                                                      Bundle params = getIntent (
    public void clickno (View view) {           ).getExtras ( );
           done (NO);                                                 if (params != null) {
    }                                                                          title = params.getString
                                                (“title”);
    public void clickyes (View view)    {                                       message =
           done (YES);                          params.getString (“msg”);
    }                                                             }
}                                                                 ...
                                                        }

                                                             public void clickno (View view) {
                                                                       done (“no”);
                                                             }

                                                             public void clickyes (View view) {
                                                                       done (“yes”);
                                                             }

                                                             private void done (String result) {
                                                                       Intent intent = new Intent ( );
                                                                       intent.putExtra (“RESULT”, result);
                                                                       setResult (Activity.RESULT_OK,
                                                intent);
Helper Class for Intent Callbacks: Launcher

Launcher encapsulates the gory details of creating and firing Intents
     many convenient constructors
     manages parameters passing
     creates Intent
     launch method invokes: startActivity (...)
    or startActivityForResult (...)

                                                Launcher

             + Launcher (: Activity, eventid : int)
             + Launcher (: Activity, param : String)
             + Launcher (: Activity, eventid : int, param : String)
             + Launcher (: Activity, title : int, msg : int)
             + Launcher (: Activity, title : String, msg : String)
             + Launcher (: Activity, eventid : int, title : int, msg : int)
             + Launcher (: Activity, eventid : int, title : int, msg : int, list : String[ ])

             + Launch (cls : Class<?>) : void

             + setgravity (gravity : int) : void
             + setmaxdigits (: int) : vod
             + setmindigits (: int) : void
             + setmultiline( ) : void
             + setparam (key : String, value : String) : void
             + trapabort( ) : void
public class AnActiviy extends SuperActivity {
                                            static private final int                 COMPLETE      = 1,
                                                                                            UPDATE = 2,
Voila! A Unified Approach to Callbacks:                                                     GOTYESNO
                                                      = 3;
                                                      ...
     Worker Thread
                                              public void dosomething (...) {
     Domain-to-Interface                              (new Worker (this, COMPLETE)).start ( );
                                              }
     Intent-to-Intent                         public void observe (Domainthing thing) {
                                                      thing.addobserver (this, UPDATE);
                                              }

                                              public void asktyesno( ) {
                                                      Launcher                launcher;
                                                      ...
                                                      lancher = new Launcher (this, GOTYESNO,
                                                          R.string.delete_all_title, R.string.delete_all_msg);
                                                      launcher.launch (ActivityGetyesnodialog.class);
                                              }

                                              public void event (int eventid, Object data) {
                                                      switch (eventid) {
                                                       case COMPLETE:          // thread-to- thread callbackevent
                                                         ...
                                                         break;

                                                       case UPDATE:             // domain-to-interface callback
                                          event
                                                         ...
                                                         break;

                                                       case GOTYESNO:           // intent-to-intent callback event
                                                         if (isyes()) {
                                                                   ...
                                                         }
                                                         break;
                                                      }
                                              }
                                          }
An Unsatisfying Aspect

I commonly apply Eventconsumer to Activities:
   extend Superactivity
   implemement event method


It is natural to apply it to ListActivity too:
   create SuperListActivity
   must duplicate (or delegate) methods similar to those in
  SuperActivity
Event Consumer
         Activity



                        SuperActivity «abstract»                                                Eventconsumer
                                                                                                  «interface»
+ event (eventid : int) : void
+ event (eventid : int, data : Object) : void                                      + event (eventid : int) : void
+ event (eventid : int, data : Object, resultcode : int) : void                    + event (eventid : int, data : Object
+ onActivityResult (eventid : int, resultcode : int, intent : Intent) : void
# abort ( ) : void
# done (response : int) : void
# done (response : String) : void
# getparamstring ( ) : String
# getresult ( ) : int
# getresultstring ( ) : String
# isabort ( ) : boolean
# isuccess ( ) : boolean
# isyes ( ) : boolean                                                                               AnActivity

                                                                                + func ( ) : void
                                                                                + event (eventid : int, data : Object) : void
             DialogActivity «abstract»

+ onCreate (bundle: Bundle, layout : int) : void
+ event (eventid : int, data : Object) : void
+ getitlefield ( ) : TextView
+ getmsgfield ( ) : TextView
+ onBackPressed ( ) : void                                             ActivityGetyesnodialog

                                                           + onCreate (bundle : Bundle) : void
                                                           + clickno (View view) : void
                                                           + clickyes (View view) : void

Más contenido relacionado

La actualidad más candente

Java_practical_handbook
Java_practical_handbookJava_practical_handbook
Java_practical_handbookManusha Dilan
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency GotchasAlex Miller
 
Cleanup and new optimizations in WPython 1.1
Cleanup and new optimizations in WPython 1.1Cleanup and new optimizations in WPython 1.1
Cleanup and new optimizations in WPython 1.1PyCon Italia
 
20070329 Object Oriented Programing Tips
20070329 Object Oriented Programing Tips20070329 Object Oriented Programing Tips
20070329 Object Oriented Programing TipsShingo Furuyama
 
Java весна 2013 лекция 2
Java весна 2013 лекция 2Java весна 2013 лекция 2
Java весна 2013 лекция 2Technopark
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Juan Pablo
 
Vaadin7 modern-web-apps-in-java
Vaadin7 modern-web-apps-in-javaVaadin7 modern-web-apps-in-java
Vaadin7 modern-web-apps-in-javaJoonas Lehtinen
 
2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avancees2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avanceesNathaniel Richand
 
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."sjabs
 
Introduction à dart
Introduction à dartIntroduction à dart
Introduction à dartyohanbeschi
 
Design pattern - part 3
Design pattern - part 3Design pattern - part 3
Design pattern - part 3Jieyi Wu
 
Design pattern part 2 - structural pattern
Design pattern part 2 - structural patternDesign pattern part 2 - structural pattern
Design pattern part 2 - structural patternJieyi Wu
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomerzefhemel
 
Data structures lab
Data structures labData structures lab
Data structures labRagu Ram
 

La actualidad más candente (20)

Java_practical_handbook
Java_practical_handbookJava_practical_handbook
Java_practical_handbook
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency Gotchas
 
Awt
AwtAwt
Awt
 
Cleanup and new optimizations in WPython 1.1
Cleanup and new optimizations in WPython 1.1Cleanup and new optimizations in WPython 1.1
Cleanup and new optimizations in WPython 1.1
 
20070329 Object Oriented Programing Tips
20070329 Object Oriented Programing Tips20070329 Object Oriented Programing Tips
20070329 Object Oriented Programing Tips
 
Python tour
Python tourPython tour
Python tour
 
Java весна 2013 лекция 2
Java весна 2013 лекция 2Java весна 2013 лекция 2
Java весна 2013 лекция 2
 
Map struct
Map structMap struct
Map struct
 
Game Lab
Game LabGame Lab
Game Lab
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Vaadin7 modern-web-apps-in-java
Vaadin7 modern-web-apps-in-javaVaadin7 modern-web-apps-in-java
Vaadin7 modern-web-apps-in-java
 
2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avancees2011 nri-pratiques tests-avancees
2011 nri-pratiques tests-avancees
 
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Introduction à dart
Introduction à dartIntroduction à dart
Introduction à dart
 
Design pattern - part 3
Design pattern - part 3Design pattern - part 3
Design pattern - part 3
 
Design pattern part 2 - structural pattern
Design pattern part 2 - structural patternDesign pattern part 2 - structural pattern
Design pattern part 2 - structural pattern
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomer
 
Data structures lab
Data structures labData structures lab
Data structures lab
 

Destacado

Open research open education stracke with results christian m stracke ignasi ...
Open research open education stracke with results christian m stracke ignasi ...Open research open education stracke with results christian m stracke ignasi ...
Open research open education stracke with results christian m stracke ignasi ...EIFLINQ2014
 
Trabajo practico Daiana Benitez
Trabajo practico Daiana BenitezTrabajo practico Daiana Benitez
Trabajo practico Daiana Benitez3248486
 
Medidas difusas para comparación de TFBSs.
Medidas difusas para comparación de TFBSs.Medidas difusas para comparación de TFBSs.
Medidas difusas para comparación de TFBSs.Alberto Labarga
 
Copyright, copyleft y licencias Creative Commons
Copyright, copyleft y licencias  Creative CommonsCopyright, copyleft y licencias  Creative Commons
Copyright, copyleft y licencias Creative CommonsManuel Rodríguez Gómez
 
Analysis crop trials using climate data
Analysis crop trials using climate dataAnalysis crop trials using climate data
Analysis crop trials using climate dataAlberto Labarga
 

Destacado (7)

Open research open education stracke with results christian m stracke ignasi ...
Open research open education stracke with results christian m stracke ignasi ...Open research open education stracke with results christian m stracke ignasi ...
Open research open education stracke with results christian m stracke ignasi ...
 
2 ignasi labastida creative commons
2 ignasi labastida   creative commons2 ignasi labastida   creative commons
2 ignasi labastida creative commons
 
Trabajo practico Daiana Benitez
Trabajo practico Daiana BenitezTrabajo practico Daiana Benitez
Trabajo practico Daiana Benitez
 
Medidas difusas para comparación de TFBSs.
Medidas difusas para comparación de TFBSs.Medidas difusas para comparación de TFBSs.
Medidas difusas para comparación de TFBSs.
 
Estatuto tecnomol 2011
Estatuto tecnomol 2011Estatuto tecnomol 2011
Estatuto tecnomol 2011
 
Copyright, copyleft y licencias Creative Commons
Copyright, copyleft y licencias  Creative CommonsCopyright, copyleft y licencias  Creative Commons
Copyright, copyleft y licencias Creative Commons
 
Analysis crop trials using climate data
Analysis crop trials using climate dataAnalysis crop trials using climate data
Analysis crop trials using climate data
 

Similar a Mattbrenner

That’s My App - Running in Your Background - Draining Your Battery
That’s My App - Running in Your Background - Draining Your BatteryThat’s My App - Running in Your Background - Draining Your Battery
That’s My App - Running in Your Background - Draining Your BatteryMichael Galpin
 
OBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .pptOBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .pptSaadAsim11
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
SOLID principles with Typescript examples
SOLID principles with Typescript examplesSOLID principles with Typescript examples
SOLID principles with Typescript examplesAndrew Nester
 
C# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewC# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewPaulo Morgado
 
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019David Wengier
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2Technopark
 
Lecture 4: Data Types
Lecture 4: Data TypesLecture 4: Data Types
Lecture 4: Data TypesEelco Visser
 
Android Code Puzzles (DroidCon Amsterdam 2012)
Android Code Puzzles (DroidCon Amsterdam 2012)Android Code Puzzles (DroidCon Amsterdam 2012)
Android Code Puzzles (DroidCon Amsterdam 2012)Danny Preussler
 
More on Classes and Objects
More on Classes and ObjectsMore on Classes and Objects
More on Classes and ObjectsPayel Guria
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 

Similar a Mattbrenner (20)

That’s My App - Running in Your Background - Draining Your Battery
That’s My App - Running in Your Background - Draining Your BatteryThat’s My App - Running in Your Background - Draining Your Battery
That’s My App - Running in Your Background - Draining Your Battery
 
mobl
moblmobl
mobl
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
OBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .pptOBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .ppt
 
Object-oriented Basics
Object-oriented BasicsObject-oriented Basics
Object-oriented Basics
 
mobl
moblmobl
mobl
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
662305 10
662305 10662305 10
662305 10
 
SOLID principles with Typescript examples
SOLID principles with Typescript examplesSOLID principles with Typescript examples
SOLID principles with Typescript examples
 
C# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewC# 6.0 - April 2014 preview
C# 6.0 - April 2014 preview
 
Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
 
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2
 
Lecture 4: Data Types
Lecture 4: Data TypesLecture 4: Data Types
Lecture 4: Data Types
 
Android Code Puzzles (DroidCon Amsterdam 2012)
Android Code Puzzles (DroidCon Amsterdam 2012)Android Code Puzzles (DroidCon Amsterdam 2012)
Android Code Puzzles (DroidCon Amsterdam 2012)
 
More on Classes and Objects
More on Classes and ObjectsMore on Classes and Objects
More on Classes and Objects
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Test Engine
Test EngineTest Engine
Test Engine
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
C++ programs
C++ programsC++ programs
C++ programs
 

Más de Droidcon Berlin

Droidcon de 2014 google cast
Droidcon de 2014   google castDroidcon de 2014   google cast
Droidcon de 2014 google castDroidcon Berlin
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limitsDroidcon Berlin
 
Android industrial mobility
Android industrial mobility Android industrial mobility
Android industrial mobility Droidcon Berlin
 
From sensor data_to_android_and_back
From sensor data_to_android_and_backFrom sensor data_to_android_and_back
From sensor data_to_android_and_backDroidcon Berlin
 
new_age_graphics_android_x86
new_age_graphics_android_x86new_age_graphics_android_x86
new_age_graphics_android_x86Droidcon Berlin
 
Testing and Building Android
Testing and Building AndroidTesting and Building Android
Testing and Building AndroidDroidcon Berlin
 
Matchinguu droidcon presentation
Matchinguu droidcon presentationMatchinguu droidcon presentation
Matchinguu droidcon presentationDroidcon Berlin
 
Cgm life sdk_droidcon_2014_v3
Cgm life sdk_droidcon_2014_v3Cgm life sdk_droidcon_2014_v3
Cgm life sdk_droidcon_2014_v3Droidcon Berlin
 
The artofcalabash peterkrauss
The artofcalabash peterkraussThe artofcalabash peterkrauss
The artofcalabash peterkraussDroidcon Berlin
 
Raesch, gries droidcon 2014
Raesch, gries   droidcon 2014Raesch, gries   droidcon 2014
Raesch, gries droidcon 2014Droidcon Berlin
 
Android open gl2_droidcon_2014
Android open gl2_droidcon_2014Android open gl2_droidcon_2014
Android open gl2_droidcon_2014Droidcon Berlin
 
20140508 quantified self droidcon
20140508 quantified self droidcon20140508 quantified self droidcon
20140508 quantified self droidconDroidcon Berlin
 
Tuning android for low ram devices
Tuning android for low ram devicesTuning android for low ram devices
Tuning android for low ram devicesDroidcon Berlin
 
Froyo to kit kat two years developing & maintaining deliradio
Froyo to kit kat   two years developing & maintaining deliradioFroyo to kit kat   two years developing & maintaining deliradio
Froyo to kit kat two years developing & maintaining deliradioDroidcon Berlin
 
Droidcon2013 security genes_trendmicro
Droidcon2013 security genes_trendmicroDroidcon2013 security genes_trendmicro
Droidcon2013 security genes_trendmicroDroidcon Berlin
 

Más de Droidcon Berlin (20)

Droidcon de 2014 google cast
Droidcon de 2014   google castDroidcon de 2014   google cast
Droidcon de 2014 google cast
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limits
 
crashing in style
crashing in stylecrashing in style
crashing in style
 
Raspberry Pi
Raspberry PiRaspberry Pi
Raspberry Pi
 
Android industrial mobility
Android industrial mobility Android industrial mobility
Android industrial mobility
 
Details matter in ux
Details matter in uxDetails matter in ux
Details matter in ux
 
From sensor data_to_android_and_back
From sensor data_to_android_and_backFrom sensor data_to_android_and_back
From sensor data_to_android_and_back
 
droidparts
droidpartsdroidparts
droidparts
 
new_age_graphics_android_x86
new_age_graphics_android_x86new_age_graphics_android_x86
new_age_graphics_android_x86
 
5 tips of monetization
5 tips of monetization5 tips of monetization
5 tips of monetization
 
Testing and Building Android
Testing and Building AndroidTesting and Building Android
Testing and Building Android
 
Matchinguu droidcon presentation
Matchinguu droidcon presentationMatchinguu droidcon presentation
Matchinguu droidcon presentation
 
Cgm life sdk_droidcon_2014_v3
Cgm life sdk_droidcon_2014_v3Cgm life sdk_droidcon_2014_v3
Cgm life sdk_droidcon_2014_v3
 
The artofcalabash peterkrauss
The artofcalabash peterkraussThe artofcalabash peterkrauss
The artofcalabash peterkrauss
 
Raesch, gries droidcon 2014
Raesch, gries   droidcon 2014Raesch, gries   droidcon 2014
Raesch, gries droidcon 2014
 
Android open gl2_droidcon_2014
Android open gl2_droidcon_2014Android open gl2_droidcon_2014
Android open gl2_droidcon_2014
 
20140508 quantified self droidcon
20140508 quantified self droidcon20140508 quantified self droidcon
20140508 quantified self droidcon
 
Tuning android for low ram devices
Tuning android for low ram devicesTuning android for low ram devices
Tuning android for low ram devices
 
Froyo to kit kat two years developing & maintaining deliradio
Froyo to kit kat   two years developing & maintaining deliradioFroyo to kit kat   two years developing & maintaining deliradio
Froyo to kit kat two years developing & maintaining deliradio
 
Droidcon2013 security genes_trendmicro
Droidcon2013 security genes_trendmicroDroidcon2013 security genes_trendmicro
Droidcon2013 security genes_trendmicro
 

Último

Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarPrecisely
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfinfogdgmi
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.YounusS2
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxGDSC PJATK
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 

Último (20)

Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity Webinar
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdf
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptx
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 

Mattbrenner

  • 1. A Unified Approach to Callbacks in Android Matt Brenner – UnME2, Inc. mbrenner@unme2.com Droidcon Berlin 2013
  • 2. Background Knowledge This talk will include discussion of, threads Interfaces callbacks Observer Design Pattern and make extensive use of UML. Don't worry, we'll “fill in” all gaps along the way!
  • 3. A Unified Approach to Callbacks in Android In Java, callbacks commonly occur within processes: between threads to decouple domain / interface (e.g. Observer)
  • 4. “Worker Thread” Callback public Interface Requester { public void complete ( ); Requester } «interface» public class Mainclass implements Requester { + complete( ) : void ... public void dosomething (...) { ... (new Worker (this)).start (); } Mainclass public void complete ( ) { + dosomething (...) : void ... + complete( ) : void } ... } public class Worker extends Thread { private Requester requester_; Thread ... public Worker (Requester requester) { requester_ = requester } ... public void run( ) { Worker ... requester_.complete ( ); + Worker (requester : Requester) } + run ( ) : void } ...
  • 5. “Domain-to-Interface” Callback (Observer Pattern) Observer public class Widget implements Observer { «interface» ... public Widget (Domainthing thing) { + update (:Observable, data : Object) : void ... thing.addObserver (this); } public void update (Observable obs, Object Widget data) { ... + Widget (:Domainthing) } + update (:Observable, data : Object) : void } ... public class Domainthing extends Observable { Observable ... private void domainchange (Object data ) { + addObserver (:Observer) : void + setChanged ( ) : void ... setChanged ( ); + notifyObservers (:Object) : void notifyObservers (data); } } Domainthing
  • 6. Android Makes Extensive Use Intents Intents are used: for inter-process and inter-Activity comms to invoke Activities (passing params) to callback from one Activity to another (return a result)
  • 7. Activity Callback (Calling Activity) public class AnActiviy extends Activity { static private final int GOTYESNO = 1, ... public void askyesno( ) { Intent intent; ... intent = new Intent (this, ActivityGetyesno.class); intent.putExtra (“title”, R.string.delete_all_title); intent.putExtra (“msg”, R.string.delete_all_msg); startActivityForResult (intent, GOTYESNO); } protected void onActivityResult (int id, int result, Intent data) { if (id == GOTYESNO) { if (data.hasExtra (“RESULT”)) { result = data.getExtras( ).getString (“RESULT”); if (result.equals (“yes”)) { ... } } } } ... }
  • 8. Activity Callback (Called Activity) public class ActivityGetyesno extends Activity { ... protected void onCreate (Bundle bundle) { super.onCreate (bundle); String title, message; title = message = null; Bundle params = getIntent ( ).getExtras ( ); if (params != null) { title = params.getString (“title”); message = params.getString (“msg”); } ... } public void clickno (View view) { done (“no”); } public void clickyes (View view) { done (“yes”); } private void done (String result) { Intent intent = new Intent ( ); intent.putExtra (“RESULT”, result); setResult (Activity.RESULT_OK, intent); finish ( ); }
  • 9. A Bit of a Mess Multiple callbacks in various forms lead to: interface “clutter” multiple callback forms in a single class Intent syntax is klunky and repetitious New design pattern to the rescue: Event Consumer (Brenner)
  • 10. Event Consumer Activity SuperActivity «abstract» Eventconsumer «interface» + event (eventid : int) : void + event (eventid : int, data : Object) : void + event (eventid : int) : void + event (eventid : int, data : Object, resultcode : int) : void + event (eventid : int, data : Object + onActivityResult (eventid : int, resultcode : int, intent : Intent) : void # abort ( ) : void # done (response : int) : void # done (response : String) : void # getparamstring ( ) : String # getresult ( ) : int # getresultstring ( ) : String # isabort ( ) : boolean # isuccess ( ) : boolean # isyes ( ) : boolean AnActivity + func ( ) : void + event (eventid : int, data : Object) : void DialogActivity «abstract» + onCreate (bundle: Bundle, layout : int) : void + event (eventid : int, data : Object) : void + getitlefield ( ) : TextView + getmsgfield ( ) : TextView + onBackPressed ( ) : void ActivityGetyesnodialog + onCreate (bundle : Bundle) : void + clickno (View view) : void + clickyes (View view) : void
  • 11. Using the Event Consumer Pattern Let's see how to use Event Consumer for callbacks: from a worker-thread from domain to interface between Intents
  • 12. Event Consumer: “Worker Thread” Callback Old Version (caller) New Version (caller) NewVersion (worker) Old Version (worker) Interface Requester { public class Mainclass public class Worker extends Thread { public void complete ( ); implements Eventconsumer Requester private int requester_; eventid_; } { ... static private final int COMPLETE = 1; privateWorker (Requester requeseter) { public Eventconsumer caller_; public class Mainclass implements Requester { ... requester_ = requeseter; ... } public Worker (Eventconsumer caller, int eventid) { public void dosomething (...) { ... caller_ = caller; ... (new Worker (this, COMPLETE)).start ( public void run( = {eventid; eventid_ ) ); (new Worker (this).start (); } ... } requester_.complete( ); } public void run ( ) { public void complete ( ) { } ... ... public void event (int eventid, Object data) { caller_.event (eventid_); } switch (eventid) { } } case COMPLETE: } ... break; } } }
  • 13. Event Consumer: “Domain-to-Interface” Callback New Version Old Version public class Widget Old Version public class Widget implements Observer { implements Eventconsumer ... public class Domainthing extends Observable { { ... static private final int UPDATE = 1; private void domainchange (Object data ) { ... ... public Widget (Domainthing thing) { setChanged ( ); public void observe (Domainthing thing) { ... notifyObservers (data); thing.addobserver (this, UPDATE); thing.addObserver (this); } } } } public void event (int eventid, Object data) { public void update (Observable obs, Object data) { switch (eventid) { ... case UPDATE: } ... New Version } break; public class Domainthing { } private int eventid_; } private Eventconsumer observer_; } ... public void addobserver (Eventconsumer obs, int eventid) { observer_ = obs; eventid_ = eventid; } private void domainchange (Object data) { ... observer_.event (eventid, data); } }
  • 14. Event Consumer: Intent Callback New Version (Calling Activity) Old Version (Calling Activity) public class AnActiviy extends SuperActivity { public class AnActiviy extends Activity { static private final int GOTYESNO = 1; static private final int GOTYESNO = 1, ... ... public void askyesno( ) { public void askyesno( ) { Launcher launcher; Intent intent; ... ... lancher = new Launcher (this, GOTYESNO, intent = new Intent (this, ActivityGetyesno.class); R.string.delete_all_title, intent.putExtra (“title”, R.string.delete_all_title); R.string.delete_all_msg); intent.putExtra (“msg”, R.string.delete_all_msg); startActivityForResult (intent, GOTYESNO); launcher.launch (ActivityGetyesno.class); ... } } protected void onActivityResult (int id, int result,Intent data) public void event (int eventid, Object data) { { switch (eventid) { if (id == GOTYESNO) { case GOTYESNO: if (data.hasExtra (“RESULT”)) { if (isyes()) { result = data.getExtras( ).getString ... (“RESULT”); } if (result.equals (“yes”)) { break; ... } } } } } } } }
  • 15. Event Consumer: Intent Callback New Version (Called Old Version (Called Activity) Activity) ActivityGetyesno public class public class ActivityGetyesno extends Activity { extends DialogActivity ... { protected void onCreate (Bundle bundle) { public void onCreate (Bundle bundle) { super.onCreate (bundle); super.onCreate (bundle, R.layout.dialog_yesno); String title, message; ... } title = message = null; Bundle params = getIntent ( public void clickno (View view) { ).getExtras ( ); done (NO); if (params != null) { } title = params.getString (“title”); public void clickyes (View view) { message = done (YES); params.getString (“msg”); } } } ... } public void clickno (View view) { done (“no”); } public void clickyes (View view) { done (“yes”); } private void done (String result) { Intent intent = new Intent ( ); intent.putExtra (“RESULT”, result); setResult (Activity.RESULT_OK, intent);
  • 16. Helper Class for Intent Callbacks: Launcher Launcher encapsulates the gory details of creating and firing Intents many convenient constructors manages parameters passing creates Intent launch method invokes: startActivity (...) or startActivityForResult (...) Launcher + Launcher (: Activity, eventid : int) + Launcher (: Activity, param : String) + Launcher (: Activity, eventid : int, param : String) + Launcher (: Activity, title : int, msg : int) + Launcher (: Activity, title : String, msg : String) + Launcher (: Activity, eventid : int, title : int, msg : int) + Launcher (: Activity, eventid : int, title : int, msg : int, list : String[ ]) + Launch (cls : Class<?>) : void + setgravity (gravity : int) : void + setmaxdigits (: int) : vod + setmindigits (: int) : void + setmultiline( ) : void + setparam (key : String, value : String) : void + trapabort( ) : void
  • 17. public class AnActiviy extends SuperActivity { static private final int COMPLETE = 1, UPDATE = 2, Voila! A Unified Approach to Callbacks: GOTYESNO = 3; ... Worker Thread public void dosomething (...) { Domain-to-Interface (new Worker (this, COMPLETE)).start ( ); } Intent-to-Intent public void observe (Domainthing thing) { thing.addobserver (this, UPDATE); } public void asktyesno( ) { Launcher launcher; ... lancher = new Launcher (this, GOTYESNO, R.string.delete_all_title, R.string.delete_all_msg); launcher.launch (ActivityGetyesnodialog.class); } public void event (int eventid, Object data) { switch (eventid) { case COMPLETE: // thread-to- thread callbackevent ... break; case UPDATE: // domain-to-interface callback event ... break; case GOTYESNO: // intent-to-intent callback event if (isyes()) { ... } break; } } }
  • 18. An Unsatisfying Aspect I commonly apply Eventconsumer to Activities: extend Superactivity implemement event method It is natural to apply it to ListActivity too: create SuperListActivity must duplicate (or delegate) methods similar to those in SuperActivity
  • 19. Event Consumer Activity SuperActivity «abstract» Eventconsumer «interface» + event (eventid : int) : void + event (eventid : int, data : Object) : void + event (eventid : int) : void + event (eventid : int, data : Object, resultcode : int) : void + event (eventid : int, data : Object + onActivityResult (eventid : int, resultcode : int, intent : Intent) : void # abort ( ) : void # done (response : int) : void # done (response : String) : void # getparamstring ( ) : String # getresult ( ) : int # getresultstring ( ) : String # isabort ( ) : boolean # isuccess ( ) : boolean # isyes ( ) : boolean AnActivity + func ( ) : void + event (eventid : int, data : Object) : void DialogActivity «abstract» + onCreate (bundle: Bundle, layout : int) : void + event (eventid : int, data : Object) : void + getitlefield ( ) : TextView + getmsgfield ( ) : TextView + onBackPressed ( ) : void ActivityGetyesnodialog + onCreate (bundle : Bundle) : void + clickno (View view) : void + clickyes (View view) : void