Oct 12 | 8:55 AM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Oct 12 | 9:05 AM |
Mathias | has entered the room |
Mathias |
Hey
|
Mark M. |
hello, Mathias!
|
Mark M. |
how can I help you today?
|
Mathias |
(just fyi, finished the Firebase-push stuff. It was a nightmare :) )
|
Mathias |
I just had a quick thing i wanted to run by you:
|
Mathias |
About the application object and singletons
|
Mathias |
View paste
|
Mark M. |
no, I have not done it this way
|
Oct 12 | 9:10 AM |
Mark M. |
I recommend reading https://possiblemobile.com/2013/06/context/
|
Mark M. |
this is Dave Smith's epic blog post on the roles of various contexts
|
Mark M. |
the Application singleton is OK for some things but not others
|
Mathias |
Yeah, i've read that
|
Mark M. |
in particular, it is unsuitable for displaying a UI (normally), as it won't do apply your theme
|
Mathias |
right. well in activities it's not an issue, you already have and use a context there. It's in all those utility classes, background helper classes etc etc.
|
Mark M. |
you cited "If i want to show a dialog" in your question, which is why I mentioned it
|
Mark M. |
so my concern isn't so much about the cleanliness of having the Application available as a direct singleton as I am about using the wrong context for the wrong role
|
Mathias |
oh, right. yes good point
|
Mark M. |
starting a dialog-themed activity from the Application context is OK, though you'll need FLAG_ACTIVITY_NEW_TASK, but you cannot show a Dialog except from an Activity
|
Mathias |
yeah
|
Mark M. |
so, I tend to hold onto other things as singletons (e.g., SharedPreferences, RoomDatabase) that might be created from the Application, but I don't hold onto the Application itself as a singleton
|
Mark M. |
but, that's me
|
Mark M. |
so long as you use the right context in the right places, your approach should be fine
|
Oct 12 | 9:15 AM |
Mathias |
so you basically have a MarkPreferences singleton instead? i thought about that too, you'd have to instantiate the singleton from the application though, since you need a context to get at the sharedpreferenes
|
Mathias |
i guess you could have a static reference in the application object as well. MathiasApplication.prefs or something
|
Mark M. |
it's more that I would have some sort of repository that holds the SharedPreferences, with that repository as a singleton
|
Mathias |
right, and you would populate that repository with a context from the onCreate of the Application?
|
Mark M. |
that's one possibility
|
Mark M. |
or lazy-create
|
Mark M. |
or DI
|
Mathias |
yeah, i'd probably do DI, since it's thread-safe to do it from onCreate. Then you don't need check for lazycreate every time, but that's semantics
|
Mathias |
Than i could have a "stringresourceutil" singleton that has the application context that i can call from everywhere to get at strings. It would unclutter a lot of code
|
Oct 12 | 9:20 AM |
Mark M. |
personally, I don't mind clutter
|
Mark M. |
after all, you should see my house
|
Mark M. |
:-)
|
Mathias |
hahaha yeah well...
|
Mathias |
Well, i think you're right about it perhaps being a bit too lazy to just use the application all the time. I'll stick with using contexts, but put up a couple of new singletons for prefs, strings and similar stuff
|
Mathias |
that i create in my custom Application's onCreate()
|
Oct 12 | 9:25 AM |
Mark M. |
bear in mind that onCreate() is called on the main application thread, for *anything* that kicks off a process for your app
|
Oct 12 | 9:25 AM |
Mark M. |
so, be careful about spending too much time there
|
Mathias |
ah yeah, that's a good point
|
Mark M. |
so long as the things that you are instantiating are cheap, that's fine
|
Mark M. |
but, for example, your first SharedPreferences read triggers disk I/O, to read in the XML where the values are stored
|
Mark M. |
StrictMode should yelp about this sort of thing, if you're able to use it
|
Mathias |
i create a couple of singletons there right now, like my RetroFitClient (singleton to handle network). I also have my CacheHandler that reads a couple of objects from the disk
|
Mathias |
i've had it there for years though, and never thought about stuff being slow
|
Mark M. |
for many devices, for small bits of I/O, you won't drop many frames
|
Mark M. |
and dropping frames before your UI appears is tough for users to perceive
|
Mathias |
i really want the objects to be ready when i display the application, it needs the stuff in the cache
|
Mathias |
exactly, that's why i.do it in onCreate, since nothing is visible yet
|
Mathias |
i would never do any networking...
|
Mark M. |
what's your minSdkVersion?
|
Mathias |
17
|
Mark M. |
OK
|
Mathias |
have lots of customers with old hogs for phones
|
Mark M. |
if it was below 11, I'd be more concerned
|
Mathias |
ok
|
Oct 12 | 9:30 AM |
Mark M. |
Android moving from yaffs2 to ext4 for the filesystem made disk I/O less of a problem
|
Mark M. |
and that occurred with Android 3.0
|
Mathias |
ah! didn't know that
|
Mark M. |
basically, all disk I/O was serialized, across the whole device, originally
|
Mathias |
oh, ok
|
Mathias |
wow
|
Mark M. |
so, while your I/O might be cheap, it might be blocked by background I/O done in other apps
|
Mark M. |
now, the filesystem is far more conventional
|
Mathias |
that would potentially affect my launchtime
|
Mark M. |
right
|
Mathias |
great
|
Mark M. |
cheap devices still have cheap-and-slow flash storage, and so the advice for keeping disk I/O off the main application thread still holds
|
Mathias |
Oh well, back to notifications. It really is a lot of work on android, with all the api changes between versions. Feels so unpredictable how it will appear on the device.
|
Mark M. |
push messaging on Android is a mess on a few levels
|
Mathias |
tell me about it. 2 weeks and counting...
|
Mathias |
not exclusively, but still
|
Oct 12 | 9:35 AM |
Mathias |
my favourite hack: The only way to avoid showing a notification if the user has logged out of my application is to always send the push notification as a "data" notification, with the message and header, and other parameters in a hashmap, basically. That way, my PushService is always called, and i can decide whether to show the notification or throw it away...
|
Mathias |
on IOS, i can just call the system api "unregisterForRemoteNotifications", and the phone stops showing them for my app
|
Mathias |
oh well. Thanks for your time and insights!
|
Mark M. |
happy to be useful!
|
Mathias |
have a good one
|
Mathias | has left the room |
Mark M. |
you too!
|
Oct 12 | 10:00 AM |
Mark M. | turned off guest access |