In the Google+ Android PlusClient documentation it states that you should be executing .connect() and .disconnect() in onStart() and onStop().
I have several activities (about 8) which stack on top of eachother in various ways, and about 4 of those activities will require the PlusClient.
My base activity (which all those activities use).. I'm thinking of putting the PlusClient logic in there.
Without knowing the inner workings of the PlusClient itself I'm not sure how heavyweight it is to run connect()/disconnect() all the time in loads of activities. This was not clear in the documentation referenced above. The connect() / disconnect() methods are doing network requests in a background thread. It seems wasteful to me for the user to be clicking through all the activities and it doing multiple network requests doing the same thing.
I guess I am comparing this to the Facebook Android API which to me seems to have a "Session" type pattern which presents itself as being more efficient.
Is this really the best pattern to adopt for an app which browses through multiple Activities a lot?
Can these methods cope with not having a connection elegantly?
PlusClient is designed to be a lightweight interface to Google Play services, see:
Access google plus client from multiple activities
Google Play services will manage an OAuth 2.0 access token for you which is roughly equivalent to a 'session'. When a specific Activity calls PlusClient.connect() and Google Play services already has an access token for the user for your app, it will immediately return in the onConnected() callback of your app.
As ianhanniballake says, any network calls needed to get the access token are carried out in the background, so they don't cause problems for your UI thread.
For an example of using PlusClient in a base activity take a look at the PhotoHunt example application:
https://github.com/googleplus/gplus-photohunt-client-android/tree/master/src/com/google/plus/samples/photohunt
connect() and disconnect() do all work in a background thread and therefore can be called in the UI thread (such as in onStart() or onStop()) without any affect on the performance of your application.
As long as you are calling connect()/disconnect() in onStart()/onStop(), respectively, the PlusClient will work on any number of Activities.
Related
I'm newbie in Android services and I need some help. I'm trying to understand the google's guide, but it really lacks lot's of information and i hate the fact that google automaticly translates to my language and doesn't allow me to DENY it, so i cant quote it here.
https://developer.android.com/guide/components/services
I've an app that perform long tasks on background, so I do understand that i need a service to achieve that since activities and related thread or resources might be killed by android when the app goes background.
My service monitore some stuff from user social media so i do need to use social media Apis to contact with their server. To make things easier i wrap the social media apis into one facade and my service deals only with that facade. this facade is a singleton
the user logs in-> the service starts to run in background -> at certain point the user leaves the app now starts the problem...
after the user left the app, my background service keeps running: OK
all its fields still aren't collected by GC: OK
but the inner fields of the facade singleton get released by GC and at certain point my service call singleton (not null) which calls some field that now is null: PROBLEM
how can i deal with that? how can i force android to keep those fields (aren't many) alive because they are being used by my service
PLEASE- do not ask me to make them parceable or something like this... it is a third party api i cant change
I am currently working on an messaging application for Android that communicates with other devices using Nearby Messages API. Since this is the first time that I work with this API, I would like to know if there is a pattern or strategy to handle the connections.
For instance, when the user changes the activity (e.g. opens a new conversation), I would like to keep the connection active, so I would like to work with a Connection Manager or something to keep listening and parsing the messages.
We kept working on our code, and finally we decided to implement a ConnectionManager as a single instance. This way all the activities in the application are able to access to the same methods. We also avoid to have several instances of GoogleApiClient, and then know if we are connected or not (e.g. isConnected() method).
However, we also needed in some methods the context or the activity, but we solved passing these parameters as arguments in those methods.
To sum up:
Singleton pattern: avoid creating several instances of the same GoogleApiClient
Proxy pattern: encapsulate GoogleApiClient methods in a class that handles the whole connection, instead of delegating this task on activities
In the wonderful article by Chet Haase I read this advice which I find quite important:
never make a network request in your Application object. That object
may be created when one of the app’s Services or BroadcastReceivers is
started; hitting the network will turn code that does a local update
at a specific frequency into a regular DDoS.
The application I work on currently follows this (bad) practise: it performs a user login in Application.onCreate() - on a background thread of course, but still. This is a requirement: user needs to be logged in before any activity would do any other tasks, which usually depend on logged in user. I currently do this using RxJava in a way that any activity task observables are flatMapped onto an userlogin event and it works quite nice.
So if I should take that login task out of Application, where should it go? At first I thought it would be nice to use ActivityLifecycleCallbacks and watch for the first activity to be created. But this callback (onActivityCreated) will be called after creation, which is too late for me.
So I think that this should be done by creating some BaseActivity class and putting login and other initialization calls in it's first onCreate(). But I don't feel this is too good, because I'm mixing some app-wide logic in an activity class, it's smelly...
Anything I could have missed?
SplashActivity
An activity that starts the application. It checks for resources availability and if needed, obtains them. It also checks whether there is an active user session, and if there isn't performs a log in, if there are remembered credentials, or redirects the user to the Login/Register screen
BaseActivity
An activity that is specific for your app and that holds initialization and lifecycle callback code that is applicable for all your activities in the application.
So, I have a bunch of activities. The flow is as follows:
Main Activity: I connect to Google Plus account here, then call Show Logs, to get data from Google account.
I also have About and Setting activities.
Now if I go to About then come back to Logs, Android throws error that GoogleApiClient is not connected. So should I again call the MainActivity for connecting else should I move all of the connection code to Common or Base Activity.
I am sorry if I am not clear enough.
If the GoogleApiClient is instantiated in the Main activity, once you leave that activity it will disconnect.
For your purposes you can try having multiple instances of the GoogleApiClient across your activities (might be inefficient) but Google's interface will not require the user to sign in multiple times for each activity. Each instance will access the same state.
You can check this post for more info
Access google plus client from multiple activities
Or have try to implement the connection in an AsyncTask that will keep running in the background.
Have a look at this link
http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html
The official documentation says that "Your application must have a local Service to facilitate messaging between your application and Android Market."
My question is, is this is really necessary? And if yes, why?
Wouldn't it be possible to simply bind to the MarketBillingService from an Activity's onCreate method without having to creating a local service first?
Having to create a local service that forward the requests to the remote MarketBillingService just seems a bit over-complicated.
I agree that the In-App Billing example application has a number of layers to it that seem unnecessary, but the idea of using a Service to interact with Market is a good one. This is because the process is very asynchronous (and can take a good amount of time) and some events are generated outside the workflow of a user purchase.
While the user will be interacting with some Market UI while deciding whether to purchase the "item", after this process is over there is a long back-and-forth between your app and the market app to authorize and finalize the transaction, many steps delayed while Market communicates with its servers. You don't want to hold the user up and force them to wait on that Activity simply so you can complete the purchase. You want that to be in a Service so the user can move around in the app, or leave it completely for awhile, and still be able to finalize the purchase and download the appropriate purchased content without fear of your process being removed.
Also, there are many events that may come into your application if purchases are canceled or otherwise rejected that can happen LONG after the initial purchase back-and-forth, and the user may be doing something completely different or not have their phone awake at all at that time. You want to be able to handle these events without having to pop up an Activity.
Bottom line, it's a long-running background process...which is what Services were designed for.
HTH