Best Practice for Activities that Absolutely Depend on Services

by Eric » Fri, 29 Apr 2011 03:20:04 GMT


Sponsored Links
 My application is full of Activities that are absolutely dependent on
a connection to a financial data server (trading system).  The
Activity has the following requirements:

- a user needs to be logged into the server in order to have
permission to view data
- the Activity has to query methods on the loggedOnUser to find
trading permissions
- the Activity has a large amount of UI view code that depends on
extracting values from trading orders

If the connection to the server, which I hope to implement in a
Service, is down or not connected yet, what is the best practice for
implementing the Activity, for login permission purposes, and also to
avoid NullPointerExceptions when asking for data through methods that
may return null?  And what is the best practice for publishing Service
data to the Activity?

I see a couple of solutions

- write the Activity so that it starts up no matter what the status of
the connection/Service, and in all of the Activity methods that deal
with data to guard agains NullPointerExceptions (i.e. assume anyhing
coming from the server could be null at any time

- or, in the onCreate() of the Activity, check for the existence of a
fully connected Service.  IF it's there, allow the Activity to start
and assume that all data is non-null.  if the Service disconnects,
finish() the Activity and go to an interim Activity saying,
"reconnecting please wait...'  restart the Activity when Service is
connected again.   IF the Service is NOT viable on Activity
onCreate(), finish() the Activity in onCreate() and start the
temporary "connecting please wait" Activity, and when Service is
viable again, start the main Activity back up.

-- 



Re: Best Practice for Activities that Absolutely Depend on Services

by Streets Of Boston » Fri, 29 Apr 2011 03:29:04 GMT


 It really depends on what you want.

In my app, the request to the server is made first. If this is successful 
(connection is OK, login is OK), then the data from the server is assigned 
to an Intent and this Intent is used to start an Activity to show that 
data. 

If the connection is wrong, a dialog message comes up explaining that.
If the login is wrong, then a login screen is shown. When the user logs in 
successfully from the login-screen, the request is repeated with the correct 
credentials (authorization token, session-cookie,...).


-- 


Sponsored Links


Re: Best Practice for Activities that Absolutely Depend on Services

by Eric » Fri, 29 Apr 2011 03:31:50 GMT


 


How do you handle when user hits the HOME button, user leaves the app,
Android kills the process, and they return back into that Activity?

In addition, my app has a large volume of data displayed in many
Activities, not just one set of server data / one Activity.

-- 



Re: Best Practice for Activities that Absolutely Depend on Services

by Dianne Hackborn » Fri, 29 Apr 2011 03:33:15 GMT


 or a first cut I would assume writing your activity to deal correctly with
asynchronously binding to the service and filling in its UI once it has a
connection. This is basically the same as any other situation where you
need to populate your UI from some data source -- from a content provider,
data on the network, etc. Your app *must* be able to deal with the
situation where the activity starts before the service does, so this case
must be working, and is sufficient to have a working app.

Sometimes in such situations people will have a common Activity base class
that takes care of binding to the service and such, so subclasses just need
to hook in to the point where the service is available.

The main issue you may have at this point is that your UI has some flicker,
where when it is first shown the data is empty and that gets filled in very
quickly after once the binding to the existing service is complete.

A possible trick you can use to deal with this is, if you know your service
is running in the same processes as your activities (this should be the
case), then in Service.onCreate() it can set a static variable containing
the service instance. (And of course clear it in Service.onDestroy()). Now
when you init the activity, after binding to the service you can check to
see if that variable is set and if so immediately populate your UI with the
currently running instance. This is basically an extension on the local
service sample code in the docs.

On Thu, Apr 28, 2011 at 3:19 PM, Eric <e...@alum.mit.edu> wrote:




--
Dianne Hackborn
Android framework engineer
hack...@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails. All such
questions should be posted on public forums, where I and others can see and
answer them.

--



Re: Re: Best Practice for Activities that Absolutely Depend on Services

by Dianne Hackborn » Fri, 29 Apr 2011 03:43:37 GMT


 



That is why all activities that are using the service must at the least
support the case where they bind and won't have access to the service until
some time later when the connection is established.



Another way you can approach this is to have a singleton that arbitrates
access to the service -- it binds through the application context, and has a
reference count of the current activities using it, to know when to unbind.
 (If you care about unbinding, you very well may not.)  Then each activity
gets this singleton, sets a callback, and update its UI when receiving the
callback.  If the singleton is already bound to the service, it performs the
callback immediately.

Using a singleton may be useful if there is common data being pulled out of
the service and shared between activities.  Then if Activity A has done
something to pull some data out and launches Activity B, B can immediately
get that same data without going through the service.

Of course if you are following the local service sample, the singleton
doesn't really add a whole lot since the service itself can store all of
this data in itself with the same rich Java API to access it.  The singleton
approach may still be something you like better than using a common activity
base class, depending on your preference.

-- 
Dianne Hackborn
Android framework engineer
hack...@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails.  All such
questions should be posted on public forums, where I and others can see and
answer them.

-- 



Re: Best Practice for Activities that Absolutely Depend on Services

by Streets Of Boston » Fri, 29 Apr 2011 03:46:28 GMT


 I parse the data from the service into data that can be persisted. 

If the data is small enough, the data is translated into a class that 
implements Parcelable. This parcelable is then assigned to the Intent that 
starts the Activity (using 'Extras'). When the process is killed and the 
user goes back to the Activity, Android (re)starts the Activity with the 
same Intent, including the 'Extras' that hold the original data. You don't 
need to do anything special for that.

If the data is too large to hold in a Parcelable (that is assigned to the 
Intent's Extras), then store the data in a cache (database, file, whatever 
seems best to you) and have a key to the entry of your data in the cache 
(e.g. primary key of  a database row). Assign the key to the Intent's Extras 
that starts the Activity. Then when you Activity starts 
(onCreate/onNewIntent), get the key from the Intent and read the data from 
the cache using this key.

-- 



Re: Best Practice for Activities that Absolutely Depend on Services

by Eric » Fri, 29 Apr 2011 04:01:24 GMT


 


Thank you.  I think I'll go with this, since I am porting a Java
client application to Android, and I already have data transfer
mechanisms in place.

The main thing I was asking about is, if the Service that the Activity
needs is not created and/or connected yet, should the Activity handle
that gracefully and watch out for NPE's, etc, or should the Activity
just shut itself down in favor of a temporary "Please wait for data to
load...." Activity, that then starts the original Activity back up
again when the Service is finally ready.  It sounds like all the
advice so far is to write the Activity to work independent of Service
availability, and don't bother with the temporary "Please wait..."
Activity garbage.  The advantage of that approach would be that the
main data-bearing Activity may then be written knowing the data it
needs will always be at least available (i.e. non-null), albeit
possibly out of date.  But the advantage of the suggested approach is
certainly that the Activity would be much more resilient if it can be
displayed and interacted with, without the Service being available.

One of the problems I have is that I would like to share code with the
java client desktop application, and that is complicating matters for
sure.

-- 



Re: Best Practice for Activities that Absolutely Depend on Services

by Eric » Fri, 29 Apr 2011 04:07:17 GMT


 


I didn't know about this feature?  You're saying if you just put
Extras on the Intent of the Activity (i.e. Activity.getIntent()), that
the system will use that same Intent/extras when it restarts after
HOME?  I knew you could Parcel data in onSaveInstanceState(), but I
didn't know about the ability to add stuff to the Intent.  Or, are you
simply talking about the same onSaveInstanceState() functionality that
I'm talking about?

-- 



Re: Best Practice for Activities that Absolutely Depend on Services

by Streets Of Boston » Fri, 29 Apr 2011 04:15:13 GMT


 Yes and no.

As long as your Extra in the Intent implements Parcelable properly, it 
works. Calling getIntent() in onCreate or in onNewIntent gets you the data 
that was used in the Intent that (originally) started the Activity.

If the user interacts with the Activity and thus *changes *the original 
state/data of the Activity, you may want to save these state/data changes 
when the onSaveInstanceState() is called by the OS. Then when the Activity 
is restarted (onCreate, onNewIntent), you get the original data from the 
Intent's extra and merge in the changes in the onRestoreInstanceState().


-- 



Re: Re: Best Practice for Activities that Absolutely Depend on Services

by Kostya Vasilyev » Fri, 29 Apr 2011 05:08:58 GMT


 29.04.2011 0:01, Eric :
The main thing I was asking about is, if the Service that the Activity needs is not created and/or connected yet, should the Activity handle that gracefully and watch out for NPE's, etc, or should the Activity just shut itself down in favor of a temporary "Please wait for data to load...."
Not sure why you connect NPEs vs. the service not being started yet or bound vs. the data not having been loaded yet. You should always be able to start / bind to your own service, provided it's correctly implemented.
Activity, that then starts the original Activity back up again when the Service is finally ready. It sounds like all the advice so far is to write the Activity to work independent of Service availability, and don't bother with the temporary "Please wait..." Activity garbage.
I'd do this actually... informing the user in some way that the data is being loaded is useful in my opinion. At least you could show the spinning progress wheel.
The advantage of that approach would be that the main data-bearing Activity may then be written knowing the data it needs will always be at least available (i.e. non-null), albeit possibly out of date. But the advantage of the suggested approach is certainly that the Activity would be much more resilient if it can be displayed and interacted with, without the Service being available.
The service (the Android Service in your application) should always be available, in the sense that you can always start it as needed. It might not be able to connect to the "real" Service providing the data (meaning a Web Service, or what have you), may have no data or out of date data, but that's another matter entirely. Taking the data storage and the data fetching parts for granted for a second, another piece that comes to my mind is some sort of notification mechanism. You might already have something in your existing code base... If not - Android ContentProvider stuff is pretty useful for that, but building your own notification mechanism is not difficult either (or reusing Java Observable stuff) and can be more flexible. I find it very useful (in my current project) to have the UI components register callbacks with my service, which the service then calls with various state change notifications. The dispatch is based on URIs. -- Kostya Vasilyev -- http://kmansoft.wordpress.com --



Re: Best Practice for Activities that Absolutely Depend on Services

by Doug » Fri, 29 Apr 2011 07:05:08 GMT


 




I'll add that if this scheme is used, the calling activity must
absolutely unregister its callbacks in onStop() or the singleton-
arbiter will leak the activity because the callback will contain an
implicit reference to the activity.  This situation can arise if users
are allowed to navigate away from an activity (back or forward in the
stack) without waiting to receive a response from the remote service.

If you want to avoid activity leaks AND have an activity that's not
currently started handle a response, you'll have to completely
decouple the activity instance from the singleton-arbiter.  The way I
did this for my purposes was to have the activity (or service) receive
notification from the remote service via a broadcast containing a
unique id for that request.

Doug

-- 



Re: Re: Best Practice for Activities that Absolutely Depend on Services

by Dianne Hackborn » Fri, 29 Apr 2011 08:32:51 GMT


 n Thu, Apr 28, 2011 at 7:04 PM, Doug <beafd...@gmail.com> wrote:


You can do it in onPause(), onStop(), or onDestroy(), depending on how you
want to structure your activity. You just want to make sure you do it at
some appropriate point in the lifecycle.

Well.

Honestly, it may not even be that important. If your service isn't actively
doing stuff while it is created but just responding to requests from
clients, there would be no harm in just binding to it in the first activity
and never unbunding. When all activities are in the background, the service
is only as important as the most important activity bound to it (if the
service isn't itself started), so the process will be managed in the exact
same way is one that just had background activities, and when the process is
killed any outstanding service connections it create are canceled.

(Though I guess, thinking about it, if this is all you are doing with a
service, there is probably no benefit a service is giving you anyway. A
service would only actually be helping if you had started it so it would
actually keep your process running in the background. If you aren't
starting the service, trying to use a service here is just more complexity
that is completely not needed.)

If you want to avoid activity leaks AND have an activity that's not

I would strongly recommend staying away from using broadcasts to communicate
with services. Actually doing this in a way that is secure is non-trivial
-- you need to define a signature-only permission that the send of the
broadcast requires and your application requests. (Unless you are directly
sending the broadcast to a receiver declared in your manifest, but that is
likely not going to be of any help for this situation.)

My number one rule: follow the local service sample where you have
everything running in one process. This makes things *so* much easier, and
it is trivial to do callbacks from the service to your app the same way you
would in writing normal code. In effect all the service is doing here is
just telling the system that you are doing something that you want it to
keep you around for.

--
Dianne Hackborn
Android framework engineer
hack...@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails. All such
questions should be posted on public forums, where I and others can see and
answer them.

--



Re: Best Practice for Activities that Absolutely Depend on Services

by Indicator Veritatis » Fri, 29 Apr 2011 08:36:17 GMT


 Shouldn't the OP also consider implementing all data access over the
net with a ContentProvider and then using a managed Cursor to access
it? It seems to me that would remove the need to frequently check for
null, since the managed Cursor will manage many of the lifecycle
issues for him.







-- 



Other Threads

1. System application upgrade and system app versions?

Hi,
I am having a scenario where I want to upgrade a preinstalled
application (let's say version 1.0). AFAIK, the new version (1.1) will
be installed on /data and will shadow the one in the system image.

However, if a new system image upgrade woudl contain a newer version
again (2.0), would Android run the 1.1 from /data or the 2.0 from the
new system image?

Another question - is there a <uses-sdk
android:maxSdkVersion="integer" /> tag that lets me specify that I do
not want to run on newer versions of the SDK, in case these wil
introduce unwanted behaviour and incompatible changes?

Cheers

/peter

GTalk:      neubauer.peter
Skype       peter.neubauer
Phone       +46 704 106975
LinkedIn   http://www.linkedin.com/in/neubauer
Twitter      http://twitter.com/peterneubauer

http://www.neo4j.org     - New Energy for Data - The Graph Database.
http://www.ops4j.org     - New Energy for OSS Communities - Open
Participation Software.
http://www.qi4j.org        - New Energy for Java - Domain Driven Development.

--~--~---------~--~----~------------~-------~--~----~

2. Twitter example code, importing and "resource exists with a different case"

Hey guys,

First time poster. I've been obessively hammering at learning the
platform solo for a few weeks now with alot of success. I enjoy
working on Adroid ALOT more then the Xcode. :)

Anyways, I run into a road block that I haven't been able to wiggle my
way out of. I've been attempting for the past two days to import a
Twitter code sample I found on the net to play around with it.

http://davanum.wordpress.com/2007/11/21/twitter-client-for-android-how-to-make-xml-over-http-calls/
http://theregoesdave.com/wp-content/uploads/2008/10/twitterclient.zip

When I attempt to simply start a new project with the code example
Eclipse wont allow me to because "I'm missing an activity name in the
manifest file." When I attempt to open the manifest file I get all
kinds of weird errors. When I attempt to import the resources into a
new project I get "resources exists with a different case" for my
manifest and a few other files. Looked aorund online and one source
said the second error comes from have capitals in the file names
within my file system.

A little help? Anyone? I'm such a noob. All I wanna do is figure out
how to build something that can post to Twitter.

I'm using  Eclipse Platform Version: 3.4.2 and the Android package.

--~--~---------~--~----~------------~-------~--~----~

3. Combining free and paid versions of app into a single apk - a proposal to the Google engineers

4. NullPointerException on setBackgroundResource

5. Installing APK files to your g1 mobile using Vista

6. PesterActivity gone?

7. How can I programatically launch Browser in my android application