As usual there is a lot of code in my LoginActivity
and I really would prefer to separate the Activity
responsibilities from the Google Play sign in concerns.
After rewriting this LoginActivity
code several times, in many different apps, the easy (and not so elegant) solution was create the Google API client as a Application
class object. But, since the connection state affect the UX flow, I never was happy about with this approach.
Is there an elegant way of place the GoogleApiClient
outside the Activity
?
0. TL;DR
For the impatient coder, a working version of the following implementation can be found on GitHub.
Reducing our problem only to the connection concept, we may consider that:
1. State Pattern
This is a behavioral pattern the allow an object to alter its behavior when its internal state changes. The GoF Design Patterns book describes how a TCP connection can be represent by this pattern (which is also our case).
A state from a state machine should be a
singleton
, and the easiest away of doing it in Java was to createEnum
namedState
as follows:The
Activity
will communicate with theConnection
abstract class (which holds the context) through the methodsconnect()
,disconnect()
, andrevoke()
. The current state defines how these methods will behave:2. Proxy Pattern
The class
GoogleConnection
inherits fromConnection
and encapsulates theGoogleApiClient
, so it must provide bothConnectionCallbacks
andOnConnectionFailedListener
as follows:The methods
onSignIn()
,onSignUp()
,onSignOut()
, andonRevokeAndSignOut
are required on the second step of this explanation.3. Singleton Pattern
Since there is not need to recreate this class repeatedly, we provide it as a singleton:
4. Observable Pattern
The
Connection
class extends JavaObservable
, so one or many activities can observe the state changes: