Aug 27 | 7:25 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Aug 27 | 7:35 PM |
Eric S. | has entered the room |
Mark M. |
hello, Eric!
|
Mark M. |
how can I help you today?
|
Eric S. |
Hi Mark!
|
Eric S. |
I have a more empirical question for you today about GCM
|
Eric S. |
In your experience
|
Eric S. |
How reliable is it?
|
Mark M. |
my experience with GCM can fit on the back of a postage stamp, with room left over
|
Eric S. |
Would you say it delivers 50%, 80%, 99% of the time, from the projects you have worked on?
|
Eric S. |
OK so you have not worked that much with it
|
Mark M. |
it's one of the reasons I dropped the GCM chapter in the book
|
Eric S. |
Ah ok
|
Mark M. |
the vibe I get from others is that it's probably in the high 90's
|
Aug 27 | 7:40 PM |
Eric S. |
Have you an experience with people attempting to create long-running sockets in background services?
|
Eric S. |
We only keep our socket open while forgrounded
|
Mark M. |
yeah, and it sucks on Android 6.0+, courtesy of Doze mode
|
Eric S. |
we close it 30 sec after being backgrounded
|
Mark M. |
that's a reasonable pattern
|
Eric S. |
Long-running BG sockets? Ah good point about Doze mode
|
Eric S. |
Yeah so we do that and then hope that GCM will come thru for us, but it's been spotty
|
Eric S. |
OK so my next question --
|
Eric S. |
We have a service that is started or triggered when we get a GCM message
|
Eric S. |
(obviously)
|
Eric S. |
Is this service ever terminated, assuming the OS does not have a low-memory situation?
|
Eric S. |
No, right?
|
Mark M. |
if you do not stop it, the user theoretically could, in the Settings app
|
Eric S. |
I read that services must be manually terminated by our code, otherwise the OS will only terminate in low-memory conditions
|
Eric S. |
right right
|
Eric S. |
of course
|
Mark M. |
correct
|
Eric S. |
OK got it
|
Eric S. |
So,
|
Eric S. |
I am thinking that I might implement a polling solution in our service
|
Mark M. |
and then, it doesn't so much terminate the *service*, as it terminates the *process*
|
Eric S. |
Right, the process contains the service
|
Eric S. |
because the service has access to that singleton application object
|
Eric S. |
which is where it gets access to a singleton networking object we use
|
Eric S. |
that controls all API requests, etc
|
Eric S. |
I am thinking that service should do polling
|
Eric S. |
Say, ever 10 or 30 min or something
|
Eric S. |
Since GCM has been so spotty for us
|
Mark M. |
if this is "what if GCM doesn't come through", you could treat it more as a fallback
|
Eric S. |
Right
|
Mark M. |
when a GCM message comes through, set an alarm to get control in N minutes
|
Mark M. |
including cancelling the previous alarm, if still outstanding
|
Eric S. |
I was using the sendDelayedMessage
|
Eric S. |
and Handlers
|
Mark M. |
that way, you're not polling unnecessarily, when GCM is behavingg
|
Eric S. |
right
|
Mark M. |
oh, right, OK
|
Mark M. |
I'd just use ScheduledExecutorService
|
Eric S. |
Is there a big difference?
|
Eric S. |
Is ScheduledExecutorService better than what I proposed?
|
Mark M. |
not a ton, admittedly
|
Eric S. |
OK I just ask because I am v familiar with that design pattern but not at all with ScheduledExectorService
|
Mark M. |
you have to remember to use a HandlerThread, as you don't really want to be getting control on the main application thread
|
Aug 27 | 7:45 PM |
Eric S. |
exactly
|
Eric S. |
OK
|
Mark M. |
anyway, your Handler approach is probably fine
|
Eric S. |
So polling in a service as a fallback to GCM -- that is the design pattern you would use given the problem I have described?
|
Eric S. |
Or is there a better approach you can think of?
|
Mark M. |
if by "polling" you mean "poll when GCM is not pushing", then yes
|
Mark M. |
that's the only GCM-centric approach that I am aware of
|
Mark M. |
though there can be variations in how the polling is done
|
Mark M. |
usually, I recommend that people don't try to keep services running any more than they have to
|
Eric S. |
Well
|
Eric S. |
Once GCM activates my service
|
Eric S. |
It's running indefinitely, unless I stop it, right?
|
Mark M. |
yes, with the idea that you stop it when you are no longer *actively* delivering value to the user
|
Mark M. | |
Mark M. |
watching the clock tick is not actively delivering value to the user
|
Eric S. |
True
|
Mark M. |
so long as your service is running, Android's going to try to keep your process around
|
Mark M. |
from your standpoint, that's wonderful
|
Eric S. |
For a messaging / chat app however, you never know when a new message could come in
|
Mark M. |
from the user's standpoint, not so much
|
Mark M. |
very trye
|
Mark M. |
er, true
|
Eric S. |
And given GCM's spottiness,
|
Eric S. |
OK
|
Eric S. |
Last question --
|
Eric S. |
Have you heard of this approach: https://eladnava.com/pushy-a-new-alternative-to...
|
Eric S. |
Using "MQTT"?
|
Mark M. |
I know of MQTT
|
Mark M. |
haven't heard of Pushy itself
|
Eric S. |
allegedly
|
Eric S. |
neither Facebook or Whatsapp use GCM
|
Eric S. |
they both use custom implementations that keep proprietary sockets open at all times
|
Eric S. |
that use MQTT
|
Mark M. |
MQTT is probably the leading non-GCM push solution
|
Aug 27 | 7:50 PM |
Mark M. |
however, that's where the Doze mode challenges start to creep in
|
Mark M. |
in principle, if you have an MQTT socket open on mobile data, an incoming packet should wake up the device
|
Eric S. |
OK
|
Mark M. |
and allow you to process the message
|
Eric S. |
Have you ever worked with or implemented an MQTT solution?
|
Mark M. |
I'm under the impression that Doze mode interferes with that flow, though
|
Mark M. |
not personally
|
Mark M. |
though it's on my to-do list
|
Eric S. |
And is that some kind of "new" socket or mode
|
Eric S. |
I thought a socket is a socket
|
Eric S. |
can you "tag" a socket as an MQTT socket on Android?
|
Eric S. |
Starting with version XXX or something?
|
Mark M. |
yes, but the processors treat things differently
|
Eric S. |
OK, interesting, so different devices treat an MQTT socket differently
|
Mark M. |
if you go back and watch the 2012(?) Google I|O presentation on C2DM (the GCM predecessor), they get into some of these details
|
Mark M. |
basically, it's how GCM works, to keep a long-lived socket going with minimal power usage
|
Eric S. |
Ah ok
|
Mark M. |
again, I haven't played with MQTT, particularly in the past year
|
Eric S. |
There must be some kind of native understanding of MQTT in android for this then
|
Mark M. |
not strictly for MQTT
|
Eric S. |
this is a flag I can pass in Java.io.
|
Mark M. |
just for open socket connections on mobile data
|
Mark M. |
which MQTT eventually uses, when the device falls off of WiFi
|
Eric S. |
Ah ok
|
Mark M. |
my suspicion is that with Doze mode, the MQTT-using app might not get control when the device falls off of WiFi
|
Mark M. |
but that's just an educated gues
|
Mark M. |
er, guess
|
Eric S. | |
Aug 27 | 7:55 PM |
Eric S. |
Looks like IBM also ships some kind of library that can be used for this
|
Mark M. |
yes, IBM was one of the MQTT creators, IIRC
|
Eric S. |
Ah, makes sense
|
Mark M. |
MQTT predates Android, IIRC
|
Eric S. |
OK, well, I will look into MQTT, but probly start by trying to implement polling
|
Eric S. |
Oh, interesting!
|
Mark M. |
MQTT mostly seems to be used for two cases:
|
Mark M. |
1. non-Play ecosystem devices, where GCM simply doesn't exist
|
Mark M. |
2. places where even using encrypted GCM messages might be too much exposure (e.g., medical data)
|
Eric S. |
OK
|
Eric S. |
makes sense
|
Mark M. |
the reason why I want to add an MQTT chapter in my book is that I try to promote non-Play-specific tech, where I can
|
Mark M. |
because I think a good chunk of my readership writes apps for non-Play-ecosystem devices
|
Eric S. |
That must be what they are using in China too
|
Mark M. |
that, or I think some manufacturers there have their own GCM equivalents baked in
|
Eric S. |
That's interesting that you can essentially install another GCM-substitute on your device, but it makes sense
|
Mark M. |
yeah, but GCM gets preferential treatment, with respect to stuff like Doze mode
|
Eric S. |
ah, good point
|
Mark M. |
which is why this stuff is on my list of "if anyone ever asks me for antitrust ammo against Google..."
|
Eric S. |
haha
|
Mark M. |
don't mind them shipping with their stuff baked in and pre-enabled
|
Mark M. |
but locking it so third parties cannot compete as equals has anti-competitive overtones
|
Eric S. |
yah true
|
Aug 27 | 8:00 PM |
Eric S. |
OK cool...can I ask one more question unrelated to any of this?
|
Mark M. |
go right ahead -- it's a quiet chat room tonight
|
Eric S. |
OK great --
|
Eric S. |
We are prepping a new launch
|
Eric S. |
getting lots of feedback and crash logs into Crashlytics
|
Eric S. |
at this point, most of the crashing is OOM exceptions
|
Eric S. |
sometimes my code
|
Eric S. |
sometimes OS code
|
Eric S. |
frequently image decoding or XML layout decoding
|
Eric S. |
In your experience, is this just the state of the Android world?
|
Mark M. |
it depends on the nature of the OOM
|
Eric S. |
A slow drip of OOM exceptions?
|
Mark M. |
if the OOM is because you are trying to allocate something huge, that's an app bug
|
Mark M. |
if the OOM is because you are trying to allocate something normal, that's just the state of the Android world
|
Mark M. |
(and is one of the reasons to let your process die, so you get a nice unfragmented heap)
|
Eric S. |
Yeah exactly
|
Eric S. |
these are allocating "normal" things
|
Eric S. |
and so the process dies yup
|
Mark M. |
ART helps some
|
Mark M. |
so I would hope that you're getting somewhat fewer OOMs on Android 5.0+
|
Eric S. |
OK good question -- I will inspect these logs and look at the OS version
|
Eric S. |
When you look at Crashlytics logs of projects you have helped or worked on
|
Eric S. |
Do you see a lot of OOM exceptions for "normal" things too?
|
Mark M. |
not usually
|
Eric S. |
Gosh, this is something Crashlytics could also answer since they get so much data about this...I should suggest that to them
|
Eric S. |
OK
|
Mark M. |
again, process lifetime is fairly important
|
Aug 27 | 8:05 PM |
Mark M. |
this sort of thing is one of the reasons why some people split long-running services out into a separate process
|
Mark M. |
so your UI process can die
|
Eric S. |
Ah
|
Mark M. |
so later runs of your UI get a fresh process and fresh heap
|
Eric S. |
Very good point
|
Mark M. |
personally, I think it's a bit of a Band-Aid
|
Mark M. |
but, certain types of apps may need it more
|
Mark M. |
something like yours, for example
|
Eric S. |
Yeah...that design pattern makes sense as a work-around
|
Eric S. |
OK, great
|
Eric S. |
Thank you for your help and input
|
Eric S. |
It is most appreciated!!
|
Mark M. |
you are very welcome
|
Eric S. |
Have a great evening!
|
Mark M. |
you too!
|
Aug 27 | 8:30 PM |
Eric S. | has left the room |
Mark M. | turned off guest access |