Office Hours — Today, November 15

Yesterday, November 14

Nov 15
8:55 AM
Mark M.
has entered the room
Mark M.
turned on guest access
9:20 AM
Leora
has entered the room
Mark M.
hello, Leora!
how can I help you today?
Leora
Hi Mark!
Actually this is my first time in...
And I thought I would observe other ppl's questions in the meantime
Mark M.
ah
people usually only pop in here when they have a question
Leora
Ok, got one for ya!
Mark M.
right now, you're the only one here
go right ahead!
(though if the question is "will you retitle your book as 'Booky McBookface'?", the answer is no)
:-)
Leora
Ok, so I started implementing Room, had some annoying errors, and then gave up when I realized it would be problematic to save Lists as is, without manipulation
Mark M.
you can pass List<YourEntity> into a @Dao class's @Insert, @Update, or @Delete method
Leora
I know you have an entire pdf on it, but I'm torn between ppl who really really love it, and ppl who believe a new component has no place in production
9:25 AM
Mark M.
that then depends a lot on the definition of "new"
the core Architecture Components shipped as a 1.0.0 a week ago
prior to that, I would not have shipped it in production
now, it's worth considering
but Room is merely one candidate approach to simplifying database access
it's going to be relatively popular, as it's from Google, and anything Googly gets outsized attention
Leora
I dunno, some ppl wait for .1 !
Mark M.
understood
OTOH, it's not like you'll integrate Room in a few hours
by the time you shipped something with Room, starting from (relative) scratch now, a 1.1 might well be out
(or at least a 1.0.1)
Leora
It's not that, it's in the process of researching my bugs, I found 2 answers, one was re kotlin and room, the other answred by you, the answered by....me!
an hour ago haha
Mark M.
it's always nice when your past self leaves notes for your future self :-)
Leora
hahah
so I can't query a list of objects?
like
View paste
 @Query("SELECT * FROM TeaserItem")
List getAll()
Mark M.
um, sure -- have it return List<TeaserItemEntity>
Drasko
has entered the room
Mark M.
or List<TeaserItemPOJO>
(BTW, hello, Drasko -- I will be with you shortly!)
Drasko
Hi, everybody!
Leora
hmm...I have to research the syntax more
9:30 AM
Leora
Another question please - architectual
Mark M.
let me take a question from Drasko first, and then I'll return to you
Leora
Hi Drasko!
Mark M.
Drasko: your turn! do you have a question?
Leora
ok great
Drasko
View paste
Project I currently work on is a coorporate app. Apks are stored on HockeyApp or some other cloud.
I need to create separate application which will after outside intent of an app A (which is launcher, by the way), it would check if there is a need to update an app and if it is, it would download apk and install it. I am using Samsung Knox environment, where my launcher and that app that should be developed act like almost a system apps, so I don't have constraints in that regard. What am I curious about is how my app that controls updates should be organized, meaning which components should be used in order to do these things in background. IntentService, maybe? With exported="true" in AndroidManifest.xml
Mark M.
hmmmm...
to be honest, your scenario doesn't work all that well starting with Android 8.0
the best solution that I can think of is an IntentService, but using startForeground()
Drasko
I know, that's why I am asking you. :)
Mark M.
otherwise, you may not get the APK downloaded before your service is stopped and your process is terminated
JobIntentService gives you a bigger window, but that's for purely internal use -- you cannot readily have an outside app start one
you could have a regular Service that gets exported, and all it does is turn around and start the JobIntentService, I suppose
exported="true" won't be necessary, if you have an <intent-filter>
Drasko
ok.
Mark M.
and I recommend using an <intent-filter>, so if your updater app gets refactored or something, app A doesn't need to change references to classes and such
9:35 AM
Drasko
yes, you are right. I don't have experience with apps without any UI, so how could I make one in this scenario? (just the rough sketch would be enough)
don't need to go into details.
Mark M.
um, just don't have an <activity>
your app A would need to create an explicit Intent to start the service in the updater app
Drasko
thnks
Mark M.
for example, you could use PackageManager to find the component from the implicit Intent, then create an explicit Intent using that component
I demonstrate this in the chapter on remote services and binding -- while I happen to demonstrate binding there, the explicit-Intent construction logic would work the same for a started service
without the explicit Intent, your updater app would remain in the stopped state after installation, and it would not run
note that I have not played with Knox, and so I do not know how it might impact any of this
Drasko
yes, ok.
thank you very much.
Mark M.
happy to help!
let me take a question from Leora, and I'll return to you in a bit
Leora: your turn! do you have another question?
Leora
yay!
9:40 AM
Leora
if i'm adding fragments with replace, i want to know the best solution for temporarily storing server responses
temporarily is about an hour
and that's how i got into the whole room thing
Mark M.
well, your process may not be around for an hour, so your thoughts on persisting the data make sense
Leora
and if room/sqlite is the best way to handle storing arrays of objects
Mark M.
whether you use SQLite, an ordinary file (e.g., JSON), or SharedPreferences, is up to you, though I lean towards not SharedPreferences
arrays of objects typically result in their own table
Leora
sharedprefs takes a lot of resources, no?
Mark M.
not really, but it's designed mostly for simple name/value pairs, with an eye towards PreferenceScreen-based UIs
it's not well-suited for arbitrary stuff
you can shove arbitrary stuff in there, by converting the arbitrary stuff into JSON or XML or something
Leora
yeah, so sqlite/ROOM vs file...what say you?
Mark M.
that depends a lot on the situation
for example, the right answer might be disk caching in your network API layer (e.g., OkHttp/Retrofit)
or the right answer might be to use something like Store to handle the caching
Leora
i can't cache on the network layer - that's what i wanted at first, cause they are https requests
9:45 AM
Mark M.
HTTPS shouldn't affect cacheability
Leora
Retrofit doesn't support it :(
Mark M.
um, OK
that seems like a rather large hole
Leora
it is! but then other devs answered me that duh! https shouldn't be stored
Mark M.
um, the Web would be rather broken if that were true
Leora
but i insisted that it's not login or anything, only content, so i'm cool
Mark M.
no Web browser could cache anything
Leora
hahaha
Mark M.
yes, the issue isn't HTTPS, but the role of the page
once upon a time, you might use HTTPS only for login
not anymore
regardless, "cache" to me implies a transient store, so that feels more like "serialize the stuff to JSON files" more than "roll a database"
but, that's just a gut instinct
again, the devil is in the details
Leora
ok..... our app is a streaming app, similar to netflix, and i just want to store a list of 'media items' with their image url's, etc
Mark M.
I'm not clear why that would be "cache" vs. "sync" (i.e., keeping the data locally more or less permanently)
9:50 AM
Leora
didn't understand that last part....
Mark M.
you indicated earlier that you only wanted this data for an hour
that seems short
Leora
yes...content could change
Mark M.
the items themselves (URL, images) are longer-lived
the *role* might shift (e.g., what's promoted on some launcher activity)
so, to me, that feels more like you should keep the data around (at least the small stuff) in a database, versus considering it to be stale after an hour
only update what needs to be updated after the hour (e.g., new things, roles for existing things)
and if you want to hold onto the data for a longer period of time, and the data kinda looks like tables, use SQLite (using Room or whatever)
Leora
but i will still have to make a server call for the comparison...
Mark M.
sure
Leora
hmmm
Mark M.
ideally, your server call gives you the delta: the changes that you need to apply
or, your server call gives you a cheap index, for you to compute the delta and do the remaining calls (e.g., download missing images)
Leora
haha...not in my workplace....that would be considered 'push' right?
Mark M.
not really
push would be "the server throws data at you when the data changes"
pull does not imply that we're starting from scratch
9:55 AM
Leora
didn't understand the diff sorry
9:55 AM
Mark M.
push vs. pull isn't an Android concept
it's more general than that
let's use email as an example
classic client-side email clients (i.e., not Web mail) could work on a push or a pull basis
Leora
ok
Mark M.
pull would involve asking the server every so often "hey, what's new in my inbox?"
POP3 worked this way
push would involve maintaining an open socket connection to the server, so the server can send down a message as soon as a new email arrives in the inbox
IMAP4 works this way
in Android terms, push is something like Firebase Cloud Messaging (FCM)
pull is pull-to-refresh, AlarmManager-scheduled requests for server updates, etc.
Leora
ahhh
but the server is still aware of what the client received before
Mark M.
ideally, yes
Leora
mmmm
Mark M.
based on a user account, or a timestamp, or a 'last-seen-UUID' value, or something
Leora
wow thanks so much for that lesson!
Mark M.
Drasko: sorry, I got caught up in Leora's questions -- do you have another question?
Leora
ok great, i'll ask server side
Mark M.
since we're running out of chat time
Leora
one sec...so i could potentially use file json?
Drasko
No, Mark, thanks. I am just following your conversation. :)
Leora
hi!
Mark M.
Drasko: OK
10:00 AM
Mark M.
Leora: sure, you can write JSON (using Gson, Jackson, or the JSON APIs in the Android SDK) to getFilesDir(), getCacheDir(), etc.
Leora
Thank youuuuuuuuuuu
Mark M.
and that's a wrap for today's chat
Leora
You are a god-send and i can't believe i struggled these years alone!
Mark M.
thanks for the kind words!
the transcript will be posted to https://commonsware.com/office-hours/ shortly
the next chat is tomorrow at 7:30pm US Eastern
have a pleasant day!
Leora
great :)
Leora
has left the room
Drasko
has left the room
Mark M.
turned off guest access

Yesterday, November 14

 

Office Hours

People in this transcript

  • Drasko
  • Leora
  • Mark Murphy