Writing a Web Service
Client App for
Android
© 2010 http://wolfpaulus.com
Server Side (e.g. Tomcat)
  Hessian, Binary Protocol

  Http-Session Support

Client
  hessdroid

  remote calls / async
 ...
Quick Tips
  Use Android’s R.class

  Auto-Launch an Intent at boot time

Client
  Things that can will go wrong

        ...
Switch
           Activity

           Remote
              call
            reload
Switch       users
Activity




      ...
Exposing a Service Class:
Hessian Binary Web Service Protocol

Copyright © 2010 http://wolfpaulus.com
Copyright © 2010 http://wolfpaulus.com
Java                               Hessian




Copyright © 2010 http://wolfpaulus.com
Hessian                        Java




Copyright © 2010 http://wolfpaulus.com
package com.carlsbadcubes.api;

  import java.util.Collection;



  public interface CommService {

          Collection<M...
<?xml version="1.0" encoding="UTF-8"?>
<web-app>

     <servlet>                                           defined in hessi...
Roles
         <security-role>
             <role-name>HessianService</role-name>
         </security-role>
              ...
(1)
                                         Thread


                                         Thread

                   ...
JSESSIONID = 123
                                         Thread
                                                         ...
JSESSIONID = 123            123
                                          Thread
                                         ...
The ThreadLocal Class:

           public class ThreadLocal<T> {
             public void set( T newValue );
             ...
... not in hessian.jar




   HessianHttpServlet extends HessianServlet
       implements HessianHttpService {
           ...
.. all of
                                                   HessianServlet


       HessianHttpServlet extends HessianSer...
@Override                                HessianHttpServlet
init() ..
 //
 // introspect service implementation to find out...
= Client




Copyright © 2010 http://wolfpaulus.com
hessdroid
  http://code.google.com/p/hessdroid/




String url = “http://hostname.domain:port/service”;

ServiceProxyFacto...
hessdroid
                                         http://code.google.com/p/hessdroid/




HessDroid Generified ...
Hessian...
hessdroid
                                                 http://code.google.com/p/hessdroid/




                       ...
... not in hessdroid.jar




                   HessianFactory.initialize( )


                                           ...
Hessian
                                                  Client




CommService cs = HessianFactory.create( CommService.c...
Demo
                                   Tomcat Server with a Hessian Service
                                    and a Hes...
Async ....

  Don’t run HessionFactory.create(..) in the main thread
  Don’t run remote method calls in the main thread ei...
Interface Garage {
   void openDoor();
   Car getCar();
 }



 Interface Car {
   void openDoor();
   Color getColor();
 }...
Garage garage =
HessianFactory.create( Garage.class, getClassLoader() );

// The interface Garage and the class CarImpl
//...
Use Android’s R.
XML:

<TextView
android:textColor = "@color/ink"
android:background= "@android:color/darker_gray" />

Cod...
Use Intent flags to
              control the flow.
XML: (Activity)
<activity .. android:taskAffinity=” ”
launchMode, allowTa...
Auto-Launch after boot (1 of 2)
AndroidManifest:
..
<receiver android:name=".BootNotificationReceiver">
   <intent-filter>
 ...
Auto-Launch after boot (2 of 2)
Code:

public class BootNotificationReceiver extends BroadcastReceiver {

    @Override
   ...
Things that can will go wrong
  wrong classloader:
  java.lang.IllegalArgumentException: com.pss.api.Service is not visibl...
Unlocking Android



            Android Wireless Application Development
http://twitter.com/wolfpaulus




Thanks For Coming!
Slides & Sources
Slides:
http://wolfpaulus.com/bio/talks/androidws.pdf

Code:
http://wolfpaulus.com/bio/talks/androidws.zi...
PDF Slides, 4.2MB - Wolf Paulus
PDF Slides, 4.2MB - Wolf Paulus
PDF Slides, 4.2MB - Wolf Paulus
Upcoming SlideShare
Loading in …5
×

PDF Slides, 4.2MB - Wolf Paulus

1,062 views
970 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,062
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
15
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

PDF Slides, 4.2MB - Wolf Paulus

  1. 1. Writing a Web Service Client App for Android © 2010 http://wolfpaulus.com
  2. 2. Server Side (e.g. Tomcat) Hessian, Binary Protocol Http-Session Support Client hessdroid remote calls / async Agenda
  3. 3. Quick Tips Use Android’s R.class Auto-Launch an Intent at boot time Client Things that can will go wrong Agenda
  4. 4. Switch Activity Remote call reload Switch users Activity Four item main menu Remote Call to getNext
  5. 5. Exposing a Service Class: Hessian Binary Web Service Protocol Copyright © 2010 http://wolfpaulus.com
  6. 6. Copyright © 2010 http://wolfpaulus.com
  7. 7. Java Hessian Copyright © 2010 http://wolfpaulus.com
  8. 8. Hessian Java Copyright © 2010 http://wolfpaulus.com
  9. 9. package com.carlsbadcubes.api; import java.util.Collection; public interface CommService { Collection<Message> getMessages(); Collection<User> getUsers(); } Copyright © 2010 http://wolfpaulus.com
  10. 10. <?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> defined in hessian.jar <servlet-name>myservice</servlet-name> <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> <init-param> Implementation <param-name>service-class</param-name> <param-value>com.carlsbadcubes.impl.CommServiceImpl</param-value> </init-param> <init-param> Interface <param-name>api-class</param-name> <param-value>com.carlsbadcubes.api.CommService</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>myservice</servlet-name> <url-pattern>/service/*</url-pattern> </servlet-mapping> </web-app> Copyright © 2010 http://wolfpaulus.com
  11. 11. Roles <security-role> <role-name>HessianService</role-name> </security-role> Realm <login-config> <auth-method>BASIC</auth-method> <realm-name>default</realm-name> </login-config> Access Privileges <security-constraint> <web-resource-collection> <web-resource-name>SecureConnection</web-resource-name> <url-pattern>/service/*</url-pattern> <url-pattern>/comm/*</url-pattern> ... Components <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> Groups or Principals <role-name>HessianService</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> Communication Copyright © 2010 http://wolfpaulus.com
  12. 12. (1) Thread Thread Servlet http requests : (1) : m_var created in servlet.init() (n) (1) Thread ServiceClass impl. ServiceAPI Copyright © 2010 http://wolfpaulus.com
  13. 13. JSESSIONID = 123 Thread 357 request. 789 JSESSIONID = 789 getSession() Thread 123 Servlet Session http response : Map : m_var JSESSIONID = 357 Thread ServiceClass impl. ServiceAPI Copyright © 2010 http://wolfpaulus.com
  14. 14. JSESSIONID = 123 123 Thread ThreadLocal 357 789 JSESSIONID = 789 789 Thread 123 ThreadLocal Servlet Session http request : Map http response : m_var JSESSIONID = 357 357 Thread ServiceClass ThreadLocal impl. ServiceAPI Copyright © 2010 http://wolfpaulus.com
  15. 15. The ThreadLocal Class: public class ThreadLocal<T> {   public void set( T newValue ); public T get(); public void remove();   protected T initialValue(); } Copyright © 2010 http://wolfpaulus.com
  16. 16. ... not in hessian.jar HessianHttpServlet extends HessianServlet implements HessianHttpService { ... } Copyright © 2010 http://wolfpaulus.com
  17. 17. .. all of HessianServlet HessianHttpServlet extends HessianServlet implements HessianHttpService puts HttpSession Discovery Service for Map into ThreadLocal Android Clients memory Map<String, String> getServices() Copyright © 2010 http://wolfpaulus.com
  18. 18. @Override HessianHttpServlet init() .. // // introspect service implementation to find out if we have to put the servlet into a session // if ( getInitParameter("service-class") != null ) { String className = getInitParameter("service-class"); if (className != null) { this.requiresSessionSupport = StateKeeper.class.isAssignableFrom(loadClass(className)); } if (this.requiresSessionSupport) { System.out.println(className + " has been registered for session support."); } } @Override service() .. if (this.requiresSessionSupport) { HttpServletRequest req = (HttpServletRequest) request; ThreadLocalAttrMap.set( req.getSession( true ) ); } Copyright © 2010 http://wolfpaulus.com
  19. 19. = Client Copyright © 2010 http://wolfpaulus.com
  20. 20. hessdroid http://code.google.com/p/hessdroid/ String url = “http://hostname.domain:port/service”; ServiceProxyFactory factory = new HessianProxyFactory(); factory.set ..(..); factory.set ..(..). CommService cs = factory.create( CommService.class, url , getClassLoader()); Copyright © 2010 http://wolfpaulus.com
  21. 21. hessdroid http://code.google.com/p/hessdroid/ HessDroid Generified ... HessianProxyFactory: public <T>T create( Class<T> api, String urlName, ClassLoader loader); Clientside code without casting: Service s = (Service) factory.create( Service.class, url, cl ); Copyright © 2010 http://wolfpaulus.com
  22. 22. hessdroid http://code.google.com/p/hessdroid/ Creates a Cookie Map, Maintains HttpSessions HessianHttpProxyFactory extends HessianProxyFactory { ... } Copyright © 2010 http://wolfpaulus.com
  23. 23. ... not in hessdroid.jar HessianFactory.initialize( ) Service Discovery: maps Interfaces to URLs Copyright © 2010 http://wolfpaulus.com
  24. 24. Hessian Client CommService cs = HessianFactory.create( CommService.class, getClassLoader() ) Copyright © 2010 http://wolfpaulus.com
  25. 25. Demo Tomcat Server with a Hessian Service and a Hessian based Android Client Copyright © 2010 http://wolfpaulus.com
  26. 26. Async .... Don’t run HessionFactory.create(..) in the main thread Don’t run remote method calls in the main thread either. Copyright © 2010 http://wolfpaulus.com
  27. 27. Interface Garage { void openDoor(); Car getCar(); } Interface Car { void openDoor(); Color getColor(); } Copyright © 2010 http://wolfpaulus.com
  28. 28. Garage garage = HessianFactory.create( Garage.class, getClassLoader() ); // The interface Garage and the class CarImpl // need to be available on the client to make this work: garage.openDoor(); // remote call garage.getCar().openDoor(); // local call Copyright © 2010 http://wolfpaulus.com
  29. 29. Use Android’s R. XML: <TextView android:textColor = "@color/ink" android:background= "@android:color/darker_gray" /> Code: int c0 = getResources().getColor( R.color.ink ); int c1 = getResources().getColor( android.R.color.darker_gray ); Copyright © 2010 http://wolfpaulus.com
  30. 30. Use Intent flags to control the flow. XML: (Activity) <activity .. android:taskAffinity=” ” launchMode, allowTaskReparenting, clearTaskOnLaunch, alwaysRetainTaskState, finishOnTaskLaunch ..> Code: (Intent) myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) Copyright © 2010 http://wolfpaulus.com
  31. 31. Auto-Launch after boot (1 of 2) AndroidManifest: .. <receiver android:name=".BootNotificationReceiver"> <intent-filter> <action android:name= "android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> <service android:name=".HessianService"/> </application> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/> Copyright © 2010 http://wolfpaulus.com
  32. 32. Auto-Launch after boot (2 of 2) Code: public class BootNotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { context.startService( new Intent(context, HessianService.class)); } } } Copyright © 2010 http://wolfpaulus.com
  33. 33. Things that can will go wrong wrong classloader: java.lang.IllegalArgumentException: com.pss.api.Service is not visible from class loader Use AppContext.getClassLoader() app doesn’t have Internet permission: com.caucho.hessian.client.HessianRuntimeException: java.net.SocketException: Permission denied AndroidManifest.xml <uses-permission android:name="android.permission.INTERNET"/> app cannot be debugged: need to add the debuggable attribute to the application tag in the AndroidManifest <application android:icon="@drawable/msg" android:debuggable="true"> wrong server URL (localhost doesn’t work.) com.caucho.hessian.client.HessianRuntimeException: java.net.ConnectException: / 192.168.200.120:80 - Connection refused Copyright © 2010 http://wolfpaulus.com
  34. 34. Unlocking Android Android Wireless Application Development
  35. 35. http://twitter.com/wolfpaulus Thanks For Coming!
  36. 36. Slides & Sources Slides: http://wolfpaulus.com/bio/talks/androidws.pdf Code: http://wolfpaulus.com/bio/talks/androidws.zip Email: wolf@wolfpaulus.com

×