Android REST-client applications:
       services approach
         Sharing experience
Case
Case
       New startup
Case
       New startup
Case
       New startup
Case
       New startup
Case
       New startup

          stores
          posts
          sends

         provides
          notifies
         suggests
Case
       New startup


          REST
REST
https://api.twitter.com/1/users/show.json?screen_name=roman_mazur



     {
         id : 14701612,
         name : “Roman Mazur”,
         location : “Ukraine, Kyiv”,
         …
     }
How to perform requests
@Override
public void onClick(View view) {
  URLConnection connection
    = new URL(…).openConnection();
  …
}
How to perform requests
@Override
public void onClick(View view) {
  URLConnection connection
    = new URL(…).openConnection();
  …
}
How to perform requests
• Obviously: not in the main (GUI) thread

• Using either URLConnection or HttpClient
  – both have pros and cons


• Choose context: Activity vs. Service
Why not to use activities?
• User controls activity lifecycle
• When all your activities are in background
  your process is a candidate for killing
• You’ll lose your data
Services Way
• See also
  – Google IO 2010 session
    “Developing Android REST Client Applications”
Services: our first implementation
                      Activity


           1. onStart                 4. performRequest



                ApiMethodsSupport
      (Helper for communication with service)


                          3. registerListener
            2. bind                               5. performRequest
                             (using binder)

                        Service


                            6. HTTP GET/POST/…
Services: our first implementation
• Main problem: rotations :)
  – we register listener in onStart and remove it in
    onStop
  – what if response is received while we are rotating
    the screen?
Current implementation
• Loaders!
  – are awesome since they are not recreated in case
    of configuration changes (at least in most cases)
• Custom loader
  – binds to the service
  – registers listener
  – performs request
  – gets the result
  – unbinds
How we perform requests now


@Override
public void onActivityCreated(Bundle savedInstanceState) {
  super.onActivityCreated(savedInstanceState);

    getLoaderManager().initLoader(1, null, this);

}
How we perform requests now
@Override
public Loader<ResponseData<Profile>>
    onCreateLoader(int id, Bundle args) {

    return
      new SimpleRequestBuilder<Profile>(getActivity()) { }
        .setUrl("https://api.twitter.com/1/users/show.json")
        .addParam("screen_name", "TwitterAPI")
        .getLoader();

}
How we perform requests now
@Override
public void
    onLoadFinished(Loader<ResponseData<Profile>> loader,
                   ResponseData<Profile> data) {

    if (data.isSuccessful()) {
      Profile profile = data.getModel();
      text1.setText(profile.getName());
      text2.setText(profile.getDescription());
    }

}
How we perform requests now
@Override
public void
    onLoadFinished(Loader<ResponseData<Profile>> loader,
                   ResponseData<Profile> data) {

    if (data.isSuccessful()) {
      Profile profile = data.getModel();
      text1.setText(profile.getName());
      text2.setText(profile.getDescription());
    }

}
ResponseData
•   Result code
•   Status message
•   User visible message
•   Data
Activity Side
• Request builder creates a request description
• Description is passed to a service
  – a) as an Intent
  – b) with a service binder method
    performRequest
Service Side
• Either enqueues description processing or
  performs it in the worker thread using
  AsyncTask
• Request description builds URLConnection
• Input thread is read, parsed; result is analyzed
  and then delivered to listeners
Service Side: Response Pipeline
                       URLConnection



   ContentHandler


   Parsed object


                    ResponseDataConverter


                                 ResponseData


                       ContentAnalyzer                         Listeners
                                                  Analyzed
                                                ResponseData
Conclusions
• Power
  – requests processing can be easily managed
  – requests can triggered by notifications and
    AlarmManager
• Simplicity
  – not much to learn if you are familiar with Android
    loaders
• Caveats
  – currently not everything is easy to customize
It’s open source
But we lack documentation :)




http://code.google.com/p/enroscar/
and we are preparing to release it on GitHub
Thanks!
Roman Mazur

Head of Android Unit at Stanfy
Kyiv GDD co-organizer




mazur.roman@gmail.com
+Roman Mazur
@roman_mazur

Android rest client applications-services approach @Droidcon Bucharest 2012

  • 1.
    Android REST-client applications: services approach Sharing experience
  • 2.
  • 3.
    Case New startup
  • 4.
    Case New startup
  • 5.
    Case New startup
  • 6.
    Case New startup
  • 7.
    Case New startup stores posts sends provides notifies suggests
  • 8.
    Case New startup REST
  • 9.
    REST https://api.twitter.com/1/users/show.json?screen_name=roman_mazur { id : 14701612, name : “Roman Mazur”, location : “Ukraine, Kyiv”, … }
  • 10.
    How to performrequests @Override public void onClick(View view) { URLConnection connection = new URL(…).openConnection(); … }
  • 11.
    How to performrequests @Override public void onClick(View view) { URLConnection connection = new URL(…).openConnection(); … }
  • 12.
    How to performrequests • Obviously: not in the main (GUI) thread • Using either URLConnection or HttpClient – both have pros and cons • Choose context: Activity vs. Service
  • 13.
    Why not touse activities? • User controls activity lifecycle • When all your activities are in background your process is a candidate for killing • You’ll lose your data
  • 14.
    Services Way • Seealso – Google IO 2010 session “Developing Android REST Client Applications”
  • 15.
    Services: our firstimplementation Activity 1. onStart 4. performRequest ApiMethodsSupport (Helper for communication with service) 3. registerListener 2. bind 5. performRequest (using binder) Service 6. HTTP GET/POST/…
  • 16.
    Services: our firstimplementation • Main problem: rotations :) – we register listener in onStart and remove it in onStop – what if response is received while we are rotating the screen?
  • 17.
    Current implementation • Loaders! – are awesome since they are not recreated in case of configuration changes (at least in most cases) • Custom loader – binds to the service – registers listener – performs request – gets the result – unbinds
  • 18.
    How we performrequests now @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getLoaderManager().initLoader(1, null, this); }
  • 19.
    How we performrequests now @Override public Loader<ResponseData<Profile>> onCreateLoader(int id, Bundle args) { return new SimpleRequestBuilder<Profile>(getActivity()) { } .setUrl("https://api.twitter.com/1/users/show.json") .addParam("screen_name", "TwitterAPI") .getLoader(); }
  • 20.
    How we performrequests now @Override public void onLoadFinished(Loader<ResponseData<Profile>> loader, ResponseData<Profile> data) { if (data.isSuccessful()) { Profile profile = data.getModel(); text1.setText(profile.getName()); text2.setText(profile.getDescription()); } }
  • 21.
    How we performrequests now @Override public void onLoadFinished(Loader<ResponseData<Profile>> loader, ResponseData<Profile> data) { if (data.isSuccessful()) { Profile profile = data.getModel(); text1.setText(profile.getName()); text2.setText(profile.getDescription()); } }
  • 22.
    ResponseData • Result code • Status message • User visible message • Data
  • 23.
    Activity Side • Requestbuilder creates a request description • Description is passed to a service – a) as an Intent – b) with a service binder method performRequest
  • 24.
    Service Side • Eitherenqueues description processing or performs it in the worker thread using AsyncTask • Request description builds URLConnection • Input thread is read, parsed; result is analyzed and then delivered to listeners
  • 25.
    Service Side: ResponsePipeline URLConnection ContentHandler Parsed object ResponseDataConverter ResponseData ContentAnalyzer Listeners Analyzed ResponseData
  • 26.
    Conclusions • Power – requests processing can be easily managed – requests can triggered by notifications and AlarmManager • Simplicity – not much to learn if you are familiar with Android loaders • Caveats – currently not everything is easy to customize
  • 27.
    It’s open source Butwe lack documentation :) http://code.google.com/p/enroscar/ and we are preparing to release it on GitHub
  • 28.
    Thanks! Roman Mazur Head ofAndroid Unit at Stanfy Kyiv GDD co-organizer mazur.roman@gmail.com +Roman Mazur @roman_mazur