Office Hours — Today, May 25

Tuesday, May 23

May 25
3:50 PM
Mark M.
has entered the room
Mark M.
turned on guest access
3:55 PM
Steve S.
has entered the room
Mark M.
hello, Steve!
Steve S.
Hi Mark!
Mark M.
how can I help you today?
Steve S.
View paste
I am looking for suggestions for the best way to track user sessions. 

We define a user session as “ended” when the application has been in the background for at least 30 seconds.

Currently, we are using Application.ActivityLifecycleCallbacks (https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html) to keep track if the Application is in the background or foreground… Whenever an Activity is paused we use a Handler#postDelayed for 30 seconds, and when an Activity is resumed we use Handler#removeCallbacks to clear it in the case that the user opened the app within 30 seconds.

We are still seeing cases (~35% of the time) where the Handler#run() logic for “session ended” is not running. I suspect it is because the application is being killed by Android (either due to device limitations or maybe if the user swiped the application from Recent Apps).

I was hoping to pick your brain and see what you would suggest.
Mark M.
well, as you point out, it is not possible to absolutely guarantee that you can do something X seconds after moving into the background
my question is: if your process ends before 30 seconds is up, why do you care?
is this just for analytics?
or is there something else?
Steve S.
This is mainly for analytics. (1) we want to track the "session_ended" event and (2) we would like to finish uploading the final analytics we have stored in a local database.
4:00 PM
Mark M.
well, you have bigger issues with #2 (e.g., no network connectivity at that moment)
for that, IMHO, you should be using something like JobScheduler, largely decoupled from sessions
in terms of #1, the only thing that I can suggest is track both went_to_background and session_ended, and fix up the missing session_ended events on the server
Steve S.
Is the JobScheduler available for API 14+?
Gert G.
has entered the room
Mark M.
no, only 21+
you would use AlarmManager prior to that
(BTW, hello, Gert -- I will be with you shortly!)
Steve S.
Got it
View paste
Also, have you had experience with this:
https://developer.android.com/reference/android/app/Service.html#onTaskRemoved(android.content.Intent)
Mark M.
I have seen it but haven't used it
and I am uncertain if it is reliable
the behavior of services when the user swipes away the task seems... wobbly in recent releases
based on comments that I have seen
Gert G.
Hi. No worries. No pressing matters here. :-)
Steve S.
I was curious if the 35% we were seeing was caused by swiping away from Recent Apps and causing the app to die faster
Mark M.
that is certainly possible
Steve S.
Wobbly in what way?
Mark M.
that you get the experience that you're seeing: that the service gets terminated anyway
and I don't know if onTaskRemoved() is getting called reliably
Steve S.
Haha, great :P
Mark M.
again, it's not something I have played with
and so it is definitely something to experiment with
4:05 PM
Mark M.
personally, I try very desperately to avoid counting on anything happening once we move into the background
let me take a question from Gert, and I'll return to you in a bit
Steve S.
Yeah that is probably the best assumption to have with all the variation
Mark M.
Gert: your turn! do you have a question?
Steve S.
No problem, I will take this back and look more into the AlarmManager/JobScheduler for uploading events
Thank you for your help!
Mark M.
Steve: you're welcome!
Gert G.
I'm mainly wondering about the general architecture for an application I'm making. The most concrete question is about images.
I'm allowing users to upload images as posts for everyone to see. Can I rely for caching on Picasso or should I implement my own system to really gain control over space and connection use?
Mark M.
Picasso doesn't do uploads, unless they added it somewhere and I missed it
or are you referring to using Picasso to download the images that others have uploaded?
Gert G.
Yes, exactly.
4:10 PM
Mark M.
I don't recall Picasso having a disk cache
it has a memory cache
but I thought it assumed you did disk caching at the HTTP layer (e.g., via OkHttp)
perhaps my memory is fuzzy
Gert G.
ah, ok, I'll look into that
Mark M.
if your sole concern is the memory cache, Picasso's is probably fine
as to OkHttp's disk cache... if all you want is a cache, it's probably fine
basically, it's a question of whether you consider the downloaded images to be part of the data model or not
if the real part of the data model is the URL to the image, and you're willing to re-download the image as needed, OkHttp's cache is probably sufficient
Gert G.
Also, I'm wondering about resizing. Obviously the uploaded quality of the images has to be good enough to work on all screens. But is it worth the trouble of producing - server-side - images in different resolutions, an then serve the smallest image good enough for the asking client?
Mark M.
I can't really answer that
too many unknowns
Gert G.
yeah, I understand
Mark M.
off the cuff, I'd probably start with a middle ground: have your REST (or whatever) protocol have hooks for N resolutions, but only implement one for now
then, get a sense for the amount of bandwidth that you're using
and the overall responsiveness of the app, and so forth
the next tier up would be original plus server-side-generated thumbnail, for example
4:15 PM
Mark M.
and from there, you can scale out as needed, for differing server-side-generated resolution
Gert G.
I might go down that road, it's mainly in the overview screen that the images do slow things down.
Mark M.
my guess is that a server can do a better job of scaling the image, due to having more horsepower at its disposal
but, if disk space and server CPU time are issues, the time taken to perform the conversions may swap the client-side benefits, and so on
Steve S.
(this actually made me think of another question when you're done)
Mark M.
let me take another question from Steve, and I'll return to you shortly
Steve: back to you! let's hear your next question!
Gert G.
Sure.
Steve S.
So app is VERY image heavy (grids of thumbnails and viewpagers of full screen images). We are looking to reduce our memory footprint and are re-evaluating using Picasso and looking at other options (mainly Fresco and Glide).
After working wiht them both, Glide is very easy to swap out Picasso with and Fresco seems like it may be more worth it in the end (for at least < OS 4.X devices).
Have you used either?
Mark M.
no
based on comments/Stack Overflow questions/etc., Glide seems more popular than Fresco
4:20 PM
Steve S.
Yeah, and I know it's the recommended lib from Google
Mark M.
it is?
Steve S.
See the note at the top
Mark M.
hmmmm... they must have added that since I last viewed that page
Steve S.
Yeah it must have been within the last couple months
They are also maintaining the library
Gert G.
Interesting, I might try out Glide too.
Mark M.
the API seems fairly similar to Picasso's
Steve S.
Yeah, it's almost identical. More or less find/replace Picasso/Glide :P
Anyways, since you have worked with Picasso, is there any other approaches/steps/recommendations you have to reduce the memory footprint on allocations?
Mark M.
well, the #1 thing with bitmaps in general is to reuse an existing Bitmap object when possible, rather than allocating fresh memory
Steve S.
I am probably seeing the most OOMs in areas where we use SVGs, ViewPager of full screen images, and grid view of thumbnails
4:25 PM
Mark M.
that's inBitmap in BitmapFactory.Options
4:25 PM
Mark M.
so, I would focus on what libraries have smarts to help you tell it when it is safe to reuse a Bitmap object
since the library is the one using BitmapFactory, it would need to know that it is safe to use inBitmap
Steve S.
And how do you use that with Picasso?
Mark M.
last I checked, you don't, other than perhaps in automatic recycling scenarios (e.g., scrolling lists)
yeah, and not even there, it seems, based on a GitHub search
Glide references inBitmap in three places
so that offers some hope
Steve S.
Interesting
I am going to look into that further
Thanks for the tip!
Mark M.
Fresco also uses inBitmap, FWIW
the advantage of inBitmap is that you don't go back to the heap for a fresh byte[]
Steve S.
From my experience, Fresco almost eliminated OOMs in Android 4.X
Which was huge
But it has been causing more OOMs in 5+
Mark M.
that's kinda surprising
particularly with ART, OOMs on the whole should be declining somewhat
OTOH, screen resolutions keep climbing, meaning you may be trying to have larger images
4:30 PM
Steve S.
Yeah, but I mean increased from the natural flow of OOM errors we had before swapping Picasso for Fresco
Mark M.
that's odd
I haven't a clue why that would happen
the key with bitmaps and OOM is heap fragmentation
OOM on Android means "we do not have a single contiguous block of heap space for your allocation"
Steve S.
It's allocating huge chunks of memory even after resizing/downsampling for some reason
Mark M.
that's bad
Steve S.
That seems to be the issue
Mark M.
I haven't done a comparative stress test on these libraries for that sort of scenario
mostly because I haven't been involved in image-heavy apps
Steve S.
Yeah
Mark M.
let me take another question from Gert, and I'll be back with you in a bit
Gert: back to you! do you have another question?
Gert G.
Yes.
My app will be a location-based sort of social networks (for pets actually). I've been using the Fused Location provider, but sometimes it gives a clearly wrong location. I've found this issue for it: https://issuetracker.google.com/issues/37058437
Have you had this? Is using the old location api a good alternative if this keeps showing up?
4:35 PM
Mark M.
outside of a couple of book examples, I don't use the fused location provider
I have heard of people getting odd results from LocationManager too, but I don't have a sense of how widespread it is
Gert G.
Because you haven't needed location or because you stick with the old api?
Mark M.
I stick with the native, non-Play Services API
which happens to be old :-)
Gert G.
ok
Mark M.
but, understand that I don't see the long-term results of a lot of my work, which is done on a consulting basis
Gert G.
I see.
Steve S.
View paste
(This article gives good suggestions for throwing away the outliers)
https://developer.android.com/guide/topics/location/strategies.html
Mark M.
so, while I haven't had LocationManager problems in ages, that doesn't mean that LocationManager is the Rock of Gibraltar, either
Steve: yes, there are a few algorithms out there for that sort of thing
Gert G.
Cool, thanks, Steve.
Mark M.
the catch with those sorts of algorithms is that they assume decent input
Steve S.
Our app is also location-based and following this has reduced our tickets for inaccurate locations significantly
Gert G.
I do have the impression the Google Maps on my phone sometimes gets the same wrong location, and it does manage to somehow correct it quickly.
Mark M.
my guess is that the problem is at least partially hardware-related
4:40 PM
Mark M.
the reports that I have seen about bad LocationManager data usually has GPS fixes with claimed good accuracy, but are seriously off
Steve S.
Ya we make different assumptions based on connectivity settings, which may affect how long we wait for locations, etc.
Mark M.
in principle, the fused location API is supposed to handle a lot of that for you
in practice, ¯\_(ツ)_/¯
Steve S.
Anyways, I have to run. Have a great day guys!
Thanks again Mark!
Mark M.
you too!
Gert G.
Bye Steve.
By the way, Mark, I'm the reformed editor, in case you hadn't made the connection. :-)
Mark M.
yes, I recognized your name
Gert G.
:-)
Mark M.
my apologies for any typos in my chat messages :-)
4:45 PM
Gert G.
hehe
Mark M.
if you have another question, go right ahead
Gert G.
I've just taken the Udacity Android Fast Track course. More work than I had bargained for, but it does force you to really dive into code. Turns out I hadn't perfectly understood everything you wrote after all. :-)
Mark M.
sorry!
Gert G.
entirely my fault I'm sure!
4:50 PM
Gert G.
O, if I can make one remark about the chapter on app widgets. For the course I needed to implement one that gets updated regularly. I struggled a bit with that, maybe it could be treated more explicitly.
Mark M.
OK, I'll look into it -- thanks!
Gert G.
Thanks for the office hour. I'm off to bed (11pm here).
See you.
Mark M.
g'night!
Gert G.
has left the room
5:00 PM
Steve S.
has left the room
Mark M.
turned off guest access

Tuesday, May 23

 

Office Hours

People in this transcript

  • Gert Gielen
  • Mark Murphy
  • Steve Strates