PDF Slides, 4.2MB - Wolf Paulus
Transcript of PDF Slides, 4.2MB - Wolf Paulus
![Page 1: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/1.jpg)
![Page 2: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/2.jpg)
Writing a Web Service Client App for Android© 2010 http://wolfpaulus.com
![Page 3: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/3.jpg)
Agenda
Server Side (e.g. Tomcat)
Hessian, Binary Protocol
Http-Session Support
Client
hessdroid
remote calls / async
![Page 4: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/4.jpg)
Quick Tips
Use Android’s R.class
Auto-Launch an Intent at boot time
Client
Things that can will go wrong
Agenda
![Page 5: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/5.jpg)
![Page 6: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/6.jpg)
Switch Activity
Switch Activity
Remote call
reload users
Remote Call to getNext
Four item main menu
![Page 7: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/7.jpg)
Copyright © 2010 http://wolfpaulus.com
Exposing a Service Class: Hessian Binary Web Service Protocol
![Page 11: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/11.jpg)
Copyright © 2010 http://wolfpaulus.com
package com.carlsbadcubes.api;
import java.util.Collection;
public interface CommService { Collection<Message> getMessages();
Collection<User> getUsers();}
Copyright © 2010 http://wolfpaulus.com
![Page 12: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/12.jpg)
Copyright © 2010 http://wolfpaulus.com
<?xml version="1.0" encoding="UTF-8"?><web-app>
<servlet> <servlet-name>myservice</servlet-name> <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
<init-param> <param-name>service-class</param-name> <param-value>com.carlsbadcubes.impl.CommServiceImpl</param-value> </init-param>
<init-param> <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
Interface
Implementation
defined in hessian.jar
![Page 13: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/13.jpg)
Copyright © 2010 http://wolfpaulus.com
Roles <security-role> <role-name>HessianService</role-name> </security-role> <login-config> <auth-method>BASIC</auth-method> <realm-name>default</realm-name> </login-config> <security-constraint> <web-resource-collection> <web-resource-name>SecureConnection</web-resource-name> <url-pattern>/service/*</url-pattern> <url-pattern>/comm/*</url-pattern>
... <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>HessianService</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint>
Groups or Principals
Communication
Components
Access Privileges
Realm
Copyright © 2010 http://wolfpaulus.com
![Page 14: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/14.jpg)
Copyright © 2010 http://wolfpaulus.com
Servlet
Thread
Thread
Thread
m_var
http requests
ServiceClassimpl.
ServiceAPI
created in servlet.init()
(1)
(1)
(1)
(n)
::
![Page 15: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/15.jpg)
Copyright © 2010 http://wolfpaulus.com
http response
JSESSIONID = 123
JSESSIONID = 789
JSESSIONID = 357
SessionMap
123
789357
Servlet
Thread
Thread
Thread
m_var
ServiceClassimpl.
ServiceAPI
::
request.getSession()
![Page 16: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/16.jpg)
Copyright © 2010 http://wolfpaulus.com
http response
JSESSIONID = 123
JSESSIONID = 789
JSESSIONID = 357
SessionMap
123
789357
http request Servlet
Thread
Thread
Thread
m_var
ServiceClassimpl.
ServiceAPI
::
123ThreadLocal
789ThreadLocal
357ThreadLocal
![Page 17: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/17.jpg)
Copyright © 2010 http://wolfpaulus.com
The ThreadLocal Class:
public class ThreadLocal<T> { public void set( T newValue ); public T get(); public void remove(); protected T initialValue();}
![Page 18: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/18.jpg)
Copyright © 2010 http://wolfpaulus.com
HessianHttpServlet extends HessianServlet implements HessianHttpService {
... }
... not in hessian.jar
![Page 19: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/19.jpg)
Copyright © 2010 http://wolfpaulus.com
.. all of HessianServlet
Discovery Service for Android Clients
Map<String, String> getServices()
puts HttpSession Map into ThreadLocal
memory
HessianHttpServlet extends HessianServlet implements HessianHttpService
![Page 20: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/20.jpg)
Copyright © 2010 http://wolfpaulus.com
HessianHttpServlet@Overrideinit() .. // // 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."); } }
@Overrideservice() ..
if (this.requiresSessionSupport) { HttpServletRequest req = (HttpServletRequest) request; ThreadLocalAttrMap.set( req.getSession( true ) ); }
![Page 22: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/22.jpg)
![Page 23: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/23.jpg)
Copyright © 2010 http://wolfpaulus.com
String url = “http://hostname.domain:port/service”;
ServiceProxyFactory factory = new HessianProxyFactory();factory.set ..(..);factory.set ..(..).
CommService cs = factory.create( CommService.class, url , getClassLoader());
hessdroidhttp://code.google.com/p/hessdroid/
![Page 24: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/24.jpg)
Copyright © 2010 http://wolfpaulus.com
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 );
hessdroidhttp://code.google.com/p/hessdroid/
![Page 25: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/25.jpg)
Copyright © 2010 http://wolfpaulus.com
Creates a Cookie Map,Maintains HttpSessions
HessianHttpProxyFactory extends HessianProxyFactory {
... }
hessdroidhttp://code.google.com/p/hessdroid/
![Page 26: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/26.jpg)
Copyright © 2010 http://wolfpaulus.com
Service Discovery:maps Interfaces to URLs
HessianFactory.initialize( )
... not in hessdroid.jar
![Page 27: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/27.jpg)
Copyright © 2010 http://wolfpaulus.com
Hessian Client
CommService cs = HessianFactory.create( CommService.class, getClassLoader() )
![Page 28: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/28.jpg)
Copyright © 2010 http://wolfpaulus.com
DemoTomcat Server with a Hessian Service and a Hessian based Android Client
![Page 29: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/29.jpg)
Async ....
Don’t run HessionFactory.create(..) in the main threadDon’t run remote method calls in the main thread either.
Copyright © 2010 http://wolfpaulus.com
![Page 30: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/30.jpg)
Interface Garage { void openDoor();
Car getCar();}
Interface Car {void openDoor();Color getColor();
}
Copyright © 2010 http://wolfpaulus.com
![Page 31: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/31.jpg)
Copyright © 2010 http://wolfpaulus.com
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 callgarage.getCar().openDoor(); // local call
![Page 32: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/32.jpg)
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
![Page 33: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/33.jpg)
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
![Page 34: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/34.jpg)
Auto-Launch after boot (1 of 2)
Copyright © 2010 http://wolfpaulus.com
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"/>
![Page 35: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/35.jpg)
Auto-Launch after boot (2 of 2)
Copyright © 2010 http://wolfpaulus.com
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));
} }}
![Page 36: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/36.jpg)
Things that can will go wrongwrong classloader:java.lang.IllegalArgumentException: com.pss.api.Service is not visible from class loaderUse AppContext.getClassLoader()
app doesn’t have Internet permission:com.caucho.hessian.client.HessianRuntimeException: java.net.SocketException: Permission deniedAndroidManifest.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
![Page 37: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/37.jpg)
Unlocking Android
Android Wireless Application Development
![Page 38: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/38.jpg)
Thanks For Coming!
http://twitter.com/wolfpaulus
![Page 39: PDF Slides, 4.2MB - Wolf Paulus](https://reader033.fdocuments.us/reader033/viewer/2022042614/558a4489d8b42a80578b4757/html5/thumbnails/39.jpg)
Slides & SourcesSlides: http://wolfpaulus.com/bio/talks/androidws.pdf
Code: http://wolfpaulus.com/bio/talks/androidws.zip
Email: [email protected]