Nov 27 | 7:20 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Nov 27 | 7:30 PM |
Aaron | has entered the room |
Mark M. |
hello, Aaron!
|
Mark M. |
how can I help you today?
|
Nov 27 | 7:35 PM |
Aaron |
hey Mark, today I have two questions, trying to understand some aspects of memory management better
|
Aaron |
here they are:
|
Aaron |
View paste
(36 more lines)
|
Aaron |
code pasted a little sloppier than it looked in my editor, sorry about that
|
Mark M. |
yeah, this chat doesn't support Markdown
|
Aaron |
yeah, not just that, also weird space problems
|
Mark M. |
for #1, "Is that all correct, or is there still some potential to leak the view in this scenario?" -- I think you're fine, though I can't be 100% certain
|
Aaron |
ok, right, but if it's OK based just on what I described there, that is good to know
|
Mark M. |
for #2, b) is distinctly different
|
Nov 27 | 7:40 PM |
Mark M. |
I would worry about the lambda having a reference to the view in that case
|
Seven | has entered the room |
Mark M. |
a) and c) would be my preferred options
|
Mark M. |
(BTW, hello Seven -- I will be with you shortly!)
|
Seven |
Hi, I just bought the book subscription and saw there was an active office hours.
|
Mark M. |
yup! I run these usually three times a week -- the calendar is there on the Warescription site
|
Aaron |
ok, so first question would be, isn't a) essentially just accessing a field with a getter method w/ getView()? I thought a) and b) were similar but c) might be different
|
Mark M. |
in your scenario a), though, the lambda itself does not have a reference to the field
|
Mark M. |
whereas in b) it does, and that is what worries me
|
Mark M. |
a) is really no different than c), other than in the particular methods that you are calling
|
Seven |
ah ok, that's cool :)
|
Mark M. |
let me take a question from Seven, and I'll be back with you shortly
|
Nov 27 | 7:45 PM |
Mark M. |
Seven: I tend to go round-robin between the participants, so everyone has a chance and I'm not trying to juggle multiple chat threads at once
|
Mark M. |
so... your turn! do you have a question?
|
Seven |
Aah nice, yes I have one
|
Seven |
I am kind of new to Room and RxJava
|
Seven |
I am trying to make a query to just get the count of entries in one table and I think I may be able to use RxJava's Single to make that query
|
Seven |
View paste
|
Mark M. |
it might need to be a Long, but otherwise that looks good
|
Seven |
Ok, and how would I call it from my code?
|
Mark M. |
well, that function would be on an interface or abstract class annotated with @Dao
|
Seven |
Ah yeah, I have that one
|
Mark M. |
and you get an instance of that DAO from your RoomDatabase subclass, via an abstract function on it
|
Seven |
But I was migrating from SQLHelper to Room
|
Seven |
View paste
|
Nov 27 | 7:50 PM |
Mark M. |
your repository can wrap your RoomDatabase and hide the implementation details from the rest of the app
|
Seven |
Now that call throws an error, I cannot access the db on the main thread
|
Mark M. |
right, Room does not like that
|
Mark M. |
but that is where your Single comes into play
|
Mark M. |
your repository can make the Single available, and your GUI code (e.g., a viewmodel) can subscribe() to the Single
|
Mark M. |
or, you can use LiveDataReactiveStreams to convert the Single into a LiveData, that you can observe
|
Seven |
Cool, I think I may find an example of that in your book
|
Mark M. |
both of those would allow the actual database I/O to occur on a background thread, but let you get the results on the main application thread
|
Mark M. |
yes, I have a few examples that show this approach
|
Mark M. |
in "Android's Architecture Components", one of the books in your subscription
|
Seven |
Yeah, I saw an intro of that book and decided to buy the whole subscription
|
Mark M. |
thanks! :-)
|
Seven |
I saw that there is an example that uses Single
|
Seven |
Thanks!!
|
Seven |
This office hours are great, did not know I would have that when buying the book
|
Seven |
You can answer Aaron questions :)
|
Seven |
I will come prepared with more structured questions next time
|
Mark M. |
OK, I will swing back to you in a bit
|
Mark M. |
sounds good!
|
Mark M. |
Aaron: your turn! do you have another question?
|
Aaron |
yes, just a couple quick follow-ups then I'm done,
|
Aaron |
in response to your last message:
|
Aaron |
yes, that makes sense about a) and c). so, it's basically like, a lambda that calls a getter doesn't risk leaking the view because it would only hold a reference to the view in whatever local scope exists at the time the lambda is executed, whereas a lambda like b) keeps the reference from the time the lambda is created and passed to the observer, until it leaves memory. accurate? I read several pieces about variable capture but none of them really went into this distinction (because it's just that obvious, I guess)
|
Mark M. |
your explanation matches my understanding
|
Nov 27 | 7:55 PM |
Mark M. |
in the end, a lambda is an instance of an anonymous inner class, just with simpler syntax
|
Aaron |
yeah, ok, good
|
Aaron |
last question,
|
Aaron |
if you are using an AIC for an observer and you want to manually unregister it, you can keep a reference to it, for example in some final member variable - if you are using a lambda instead of an AIC, then it should be possible to do a similar thing, by virtue of lambdas supporting variable initialization as a target type context, right?
|
Aaron |
i.e., assign the lambda to a variable and then pass the variable to the observer?
|
Mark M. |
I haven't tried that in Java, but I agree that it should work
|
Aaron |
ok, thanks
|
Mark M. | |
Aaron |
yep, OK
|
Aaron |
that's all I've got, thanks again and have a good night!
|
Mark M. |
you too!
|
Aaron | has left the room |
Mark M. |
Seven: back to you -- do you have another question?
|
Nov 27 | 8:00 PM |
Seven |
Yes kind of
|
Seven |
I am seeing the book on to how to use RxJava's Single
|
Seven |
It provides an example of how to use single in the DAO
|
Seven |
But I do not know what syntax would be used in my Repository
|
Mark M. |
*in* the repository would be just calling the getCount() function on your DAO
|
Mark M. |
View paste
|
Mark M. |
(actually, that would be roomDb.yourDao().getCount())
|
Mark M. |
where things get more complicated is in the *client* of the repository
|
Seven |
Ah ok, I have that now
|
Seven |
yeah yea
|
Seven |
I need to use some kind of subscription iirc
|
Mark M. |
right
|
Mark M. |
what I tend to lean towards is to use LiveDataReactiveStreams in my viewmodel
|
Mark M. |
so my viewmodel would call getCount() on the repository, then use LiveDataReactiveStreams to convert that into a LiveData, which it exposes to the activity or fragment
|
Mark M. |
the activity or fragment can then observe() that LiveData, or pass it to the layout via data binding
|
Nov 27 | 8:05 PM |
Seven |
ah ok, well I do not need to make something that complicated I think
|
Seven |
Not in this specific scenario
|
Mark M. |
well, if you go this route, you do not need to worry about cleaning up the RxJava subscription, as LiveData handles that for you as part of its lifecycle management logic
|
Seven |
How much time do we have left?
|
Mark M. |
if you want to skip the LiveData, that's fine -- you just need to remember to dispose() your subscription and arrange to observe on the main application thread
|
Mark M. |
the chat wraps at 8:30pm US Eastern -- so, ~24 minutes
|
Seven |
Ah ok, I just did not want to take more time than what you were offering
|
Seven |
Ok, I think I am having a revelation now lol
|
Seven |
I will try to just explain what I thought and please tell me what you think about it
|
Mark M. |
OK
|
Seven |
I think I still was thinking in the old way, I have this call to the db to get the count of items and only proceed in one way if I have zero items and in other way otherwise.
|
Nov 27 | 8:10 PM |
Seven |
But instead of calling the database and wait for the result I could wrap all the necessary info into a viewmodel and have that information at my disposal for whenever I need it
|
Mark M. |
yes
|
Mark M. |
though not if you use Single
|
Mark M. |
that is a one-time event
|
Seven |
Exactly
|
Mark M. |
if you want to know what the count is at a certain point in time, you request and subscribe to the Single
|
Mark M. |
with Room, if you use Observable instead of Single, you would get a stream of counts, every time the table gets modified
|
Seven |
Correct
|
Mark M. |
so, you can choose which approach better fits your requirements
|
Seven |
hmmm interesting
|
Mark M. |
but beyond that, yes, your viewmodel handles most of the "dirty work"
|
Seven |
Ok, I think that's it for now. I should be able to find out how to subscribe to the Single
|
Mark M. |
in terms of subscribing, Single and Observable look pretty much the same
|
Mark M. |
so any of my examples that show Observable should work the same if you used Single, with the only difference being how many events you might get
|
Nov 27 | 8:15 PM |
Mark M. |
IOW, don't limit yourself to Single examples
|
Seven |
Of course, I will check the whole book
|
Seven |
Thanks a lot
|
Mark M. |
you're welcome!
|
Mark M. |
BTW, these chat transcripts get posted at https://commonsware.com/office-hours/
|
Mark M. |
this chat will be added shortly after it ends
|
Seven |
ah ok did not know that
|
Seven |
Have a good night!
|
Mark M. |
you too!
|
Seven | has left the room |
Nov 27 | 8:30 PM |
Mark M. | turned off guest access |