5. About Josh Long (Spring Developer Advocate)
@starbuxman
josh.long@springsource.com
3
6. Spring Mobile
• Provides support for developing mobile web applications
– Builds on Spring MVC, focuses on server-side support
– Compliments client-side mobile frameworks
• Key Features
– Device Detection
– Site Preference Management
– Site Switcher
4
7. Device Detection
• Useful when requests by mobile devices need to be
handled differently from requests made by desktop
browsers
• Introspects HTTP requests to determine the device that
originated the request.
– Achieved by analyzing the User-Agent header and other
request headers
– In contrast to “Feature Detection” where client detects
available features
• Spring Mobile provides a DeviceResolver abstraction and
interceptor
5
9. Site Preference Management
• Device detection is often used to determine which "site"
will be served to the user
– Mobile site vs. desktop site
• Spring Mobile also provides support for “site preference
management”
• Allows the user to indicate whether he or she prefers the
mobile site or the normal site
• Remembers the user’s preference for their session
7
11. Site Switcher
• Some applications may wish to host their "mobile site" at a
different domain from their "normal site"
– For example, Google will switch you to m.google.com if you
access google.com from your mobile phone
• SiteSwitcherHandlerInterceptor can be used to redirect
mobile users to a dedicated mobile site
• Supported SiteSwitchers
– mDot - m.example.com
– dotMobi - example.mobi
9
13. Limitations of Mobile web sites
• they can’t access the native capabilities of the phone
• they require network access (no offline support)
• formatting an application to look mobile is different than
actually being a mobile application
11
18. An Introduction to Android!
• Huge and growing ecosystem of
applications and a market to boot
Expected downloads in 2011
Android Market Place 8.1 billion app downloads
Apple App Store 6 billion
* http://news.cnet.com/8301-1035_3-20103230-94/android-to-overtake-apple-in-app-downloads/
14
19. Easy to get started
• Programs are written in Java ( )
15
20. Easy to get started
• Programs are written in Java ( )
15
21. Easy to get started
• Programs are written in Java ( )
15
22. Easy APIs and concepts
• no real “applications,” only loosely coupled components
Activities describes the unit of work for one screen
Services does background work like
synchronization with a cloud
service
Content Providers component that knows how to
render and manipulate content of
a certain type
Broadcast Receivers knows how to receive and
respond to system-wide
events like screen shutoff.
* http://developer.android.com/guide/topics/fundamentals.html
16
23. A Simple Activity
package org.springframework.android.activities;
import android.app.Activity;
import android.os.Bundle;
public class HelloAndroid extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
17
24. A Simple Activity
package org.springframework.android.activities;
import android.app.Activity;
You *must* extend Android classes
import android.os.Bundle; to build proper components
public class HelloAndroid extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
17
25. A Simple Activity
package org.springframework.android.activities;
import android.app.Activity;
You *must* extend Android classes
import android.os.Bundle; to build proper components
public class HelloAndroid extends Activity {
@Override R.* refers to constants that
Android code generates for you
public void onCreate(Bundle savedInstanceState) {
that correspond to “resources”
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
17
26. Declaring the Simple Activity
/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello, Android! I am a string resource!</string>
<string name="app_name">Hello, Android</string>
</resources>
/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="@string/hello"/>
18
27. Lifecycle
• Android controls lifecycles of these components
• Registered in manifest
<activity android:name=".activities.HelloAndroid
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
19
28. Lifecycle
• Android controls lifecycles of these components
• Registered in manifest
Class is set relative to root
package specified in manifest
<activity android:name=".activities.HelloAndroid
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
19
29. Lifecycle
• Android controls lifecycles of these components
• Registered in manifest
Class is set relative to root
package specified in manifest
<activity android:name=".activities.HelloAndroid
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
you specify that an Activity is
the primary one like this
19
31. How can Maven help?
• Android4Maven
– This project compiles android.jar from source and pulls out
source and resource files to replicate android.jar in the SDK
– http://sourceforge.net/projects/android4maven/
• Maven Android SDK Deployer
– If you need to use Google maps, then you have to go this
route
– https://github.com/mosabua/maven-android-sdk-deployer
• Maven Android Plugin
– Provides support for Maven dependency management within
Android projects
– http://code.google.com/p/maven-android-plugin/
21
33. m2eclipse Support
• Maven Integration for Android Development Tools
– An Eclipse plugin that adds support for integrating
m2eclipse, Android Developer Tools, and the Maven Android
Plugin
– http://code.google.com/a/eclipselabs.org/p/m2eclipse-
android-integration/
• Maven Android archetypes
– This projects provides several Maven archetypes for
Android. These archetypes allow you to quickly bootstrap a
Maven project to develop an android application.
– https://github.com/akquinet/android-archetypes
http://blog.springsource.com/2010/12/17/spring-android-and-maven-part-1/
http://blog.springsource.com/2010/12/17/spring-android-and-maven-part-2/
23
37. Enter Spring Android!
Spring’s aim:
bring simplicity to java development
modern
data access integration mobile social security
web
The Spring framework
the cloud: lightweight traditional
CloudFoundry WebSphere
Google App Engine tc Server
Amazon Web Services Tomcat JBoss AS
BeanStalk Jetty WebLogic
Heroku (on legacy versions, too!)
26
38. What problem are we trying to solve?
• Concerns
– REST has become a popular choice for architecting both
public and private web services
– The Android runtime provides HTTP clients capable of
making HTTP connections and requests, but it does not
have a fully featured REST client
• Spring Android Solution
– The goal of Spring Android Rest Template is to provide an
easy to use, and functional REST client that supports
marshaling objects from XML and JSON.
27
39. REST
• Origin
– The term Representational State Transfer was introduced and
defined in 2000 by Roy Fielding in his doctoral dissertation.
• His paper suggests these four design principles:
– Use HTTP methods explicitly.
• POST, GET, PUT, DELETE
• CRUD operations can be mapped to these existing methods
– Be stateless.
• State dependencies limit or restrict scalability
– Expose directory structure-like URIs.
• URI’s should be easily understood
– Transfer XML, JavaScript Object Notation (JSON), or both.
• Use XML or JSON to represent data objects or attributes
28
40. Basic Rest Template Example
§ Google search example
RestTemplate restTemplate = new RestTemplate();
String url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={query}";
String result = restTemplate.getForObject(url, String.class, "SpringSource");
§ Multiple parameters
RestTemplate restTemplate = new RestTemplate();
String url = "http://example.com/hotels/{hotel}/bookings/{booking}";
String result = restTemplate.getForObject(url, String.class, "42", “21”);
29
41. Demo
• Using Spring Android to communicate with a RESTful web
service (Google Search Demo)
30
42. Spring Android Rest Template
• Based on SpringFramework
– The majority of the supporting classes are pulled from
SpringFramework.
– Modifications were made to support Android.
• RestTemplate class is the heart of the library
– Entry points for the six main HTTP methods
• DELETE - delete(...)
• GET - getForObject(...)
• HEAD - headForHeaders(...)
• OPTIONS - optionsForAllow(...)
• POST - postForLocation(...)
• PUT - put(...)
• any HTTP operation - exchange(...) and execute(...)
31
43. Spring Android Rest Template
• Http Client
– The HttpComponents HttpClient is a native HTTP client
available on the Android platform.
– HttpComponentsClientHttpRequestFactory
• Message Converters
– MappingJacksonHttpMessageConverter - object to
JSON marshaling supported via the Jackson JSON
Processor
– SimpleXmlHttpMessageConverter - object to XML
marshaling supported via the Simple XML Serializer
– SyndFeedHttpMessageConverter - RSS and Atom feeds
supported via the Android ROME Feed Reader
32
44. Spring Android Showcase
• Examples
– HTTP GET
• JSON
• XML
– HTTP GET with Parameters
• JSON
• XML
– HTTP POST
• String
• JSON
• XML
• MultiValueMap
– HTTP and GZIP
33
49. Dependency Injection on Android
• Problems with DI on Android
– hard reliance on base classes
– hard reliance on Android to manage the runtime lifecycle
• a POJO peer system would have been onerous
38
50. Dependency Injection on Android
• Lots of options
– RoboGuice
– Android Annotations
– the Android way
39
51. Dependency Injection on Android
• RoboGuice (http://code.google.com/p/roboguice/)
– Pros:
• requires you to extend RoboApplication
• You must configure your beans using the
AbstractAndroidModule
• Each Activity must extend from RoboActivity
– Cons:
• no AOP
• not small, at all!
– (400kb to a mobile application may as well be 400MBs to your
enterprise application!)
40
52. Dependency Injection on Android
• RoboGuice (http://code.google.com/p/roboguice/)
before RoboGuice
public class MyActivity extends Activity {
private TextView label;
private Drawable image;
private SearchManager searchManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myactivity);
this.label = (TextView) findViewById(R.id.mylabel);
this.image = getResources().getDrawable(R.drawable.myimage);
this.searchManager = (SearchManager) getSystemService(Activity.SEARCH_SERVICE)
}
}
41
54. Dependency Injection on Android
• RoboGuice (http://code.google.com/p/roboguice/)
with RoboGuice
public class MyActivity extends RoboActivity {
@InjectView(R.id.mylabel)
TextView label;
@InjectResource(R.drawable.myimage)
Drawable image;
@Inject
SearchManager searchManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myactivity);
}
}
41
55. Dependency Injection on Android
• RoboGuice (http://code.google.com/p/roboguice/)
with RoboGuice
public class MyActivity extends RoboActivity { used to inject other
widgets or “views”
@InjectView(R.id.mylabel)
TextView label;
@InjectResource(R.drawable.myimage)
Drawable image;
@Inject
SearchManager searchManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myactivity);
}
}
41
56. Dependency Injection on Android
• RoboGuice (http://code.google.com/p/roboguice/)
with RoboGuice
public class MyActivity extends RoboActivity { used to inject other
widgets or “views”
@InjectView(R.id.mylabel)
TextView label;
used to inject Resources
@InjectResource(R.drawable.myimage)
Drawable image;
@Inject
SearchManager searchManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myactivity);
}
}
41
57. Dependency Injection on Android
• RoboGuice (http://code.google.com/p/roboguice/)
with RoboGuice
public class MyActivity extends RoboActivity { used to inject other
widgets or “views”
@InjectView(R.id.mylabel)
TextView label;
used to inject Resources
@InjectResource(R.drawable.myimage)
Drawable image;
used to inject other objects
@Inject
SearchManager searchManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myactivity);
}
}
41
58. Dependency Injection on Android
• RoboGuice (http://code.google.com/p/roboguice/)
– Pros:
• requires you to extend RoboApplication
• You must configure your beans using the
AbstractAndroidModule
• Each Activity must extend from RoboActivity
– Cons:
• no AOP
• not small, at all!
– (400kb to a mobile application may as well be 400MBs to your
enterprise application!)
• runtime inefficiency
42
59. Beyond Dependency Injection
• Android Annotations
(http://code.google.com/p/androidannotations/)
– Pros:
• compile-time code generation means no runtime cost
• can be used side-by-side with RoboGuice
– Cons:
• extra build step
• some redundancy with RoboGuice
43
61. Beyond Dependency Injection
• Android Annotations
(http://code.google.com/p/androidannotations/)
@EActivity(R.layout.myactivity) sets the layout
public class MyActivity extends Activity {
@InjectView
TextView mylabel;
@DrawableRes(R.drawable.myimage)
Drawable image;
@SystemService
SearchManager searchManager;
}
44
62. Beyond Dependency Injection
• Android Annotations
(http://code.google.com/p/androidannotations/)
@EActivity(R.layout.myactivity) sets the layout
public class MyActivity extends Activity {
Inject another widget or
@InjectView “view”
TextView mylabel;
@DrawableRes(R.drawable.myimage)
Drawable image;
@SystemService
SearchManager searchManager;
}
44
63. Beyond Dependency Injection
• Android Annotations
(http://code.google.com/p/androidannotations/)
@EActivity(R.layout.myactivity) sets the layout
public class MyActivity extends Activity {
Inject another widget or
@InjectView “view”
TextView mylabel;
specify a resource id
@DrawableRes(R.drawable.myimage) (it is optional)
Drawable image;
@SystemService
SearchManager searchManager;
}
44
64. Beyond Dependency Injection
• Android Annotations
(http://code.google.com/p/androidannotations/)
@EActivity(R.layout.myactivity) sets the layout
public class MyActivity extends Activity {
Inject another widget or
@InjectView “view”
TextView mylabel;
specify a resource id
@DrawableRes(R.drawable.myimage) (it is optional)
Drawable image;
@SystemService Inject objects configured
SearchManager searchManager; manually
}
44
65. Dependency Injection on Android
• The Android way
– android applications all have required access to a single
“Application” class
– You can override the Application class
– Thus, instant singleton!
45
66. Dependency Injection on Android
• The Android way
public class MainApplication extends Application {
private MyService service;
@Override
public void onCreate() {
super.onCreate();
service = new MyServiceImpl();
}
public MyService getMyService() {
return this.service;
}
}
46
67. Dependency Injection on Android
• The Android way
public class MainApplication extends Application {
extend the Application
private MyService service;
@Override
public void onCreate() {
super.onCreate();
service = new MyServiceImpl();
}
public MyService getMyService() {
return this.service;
}
}
46
68. Dependency Injection on Android
• The Android way
public class MainApplication extends Application {
extend the Application
private MyService service;
@Override
public void onCreate() {
register your global
super.onCreate();
singleton services
service = new MyServiceImpl();
}
public MyService getMyService() {
return this.service;
}
}
46
69. Dependency Injection on Android
• The Android way
public class MainActivity extends Activity {
private MyService service;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainApplication app = (MainApplication) getApplication();
service = app.getMyService();
}
}
47
70. Dependency Injection on Android
• The Android way
public class MainActivity extends Activity {
get a pointer to the
private MyService service;
Application
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainApplication app = (MainApplication) getApplication();
service = app.getMyService();
}
}
47
71. Dependency Injection on Android
• The Android way
public class MainActivity extends Activity {
get a pointer to the
private MyService service;
Application
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainApplication app = (MainApplication) getApplication();
service = app.getMyService();
}
}
access your service
47