Office Hours — Today, September 22

Thursday, September 20

Mark M.
has entered the room
Mark M.
turned on guest access
Sep 22
4:10 PM
Aaron
has entered the room
Mark M.
hello, Aaron!
how can I help you today?
Aaron
Hey Mark, just finishing typing up my question, just one sec
4:15 PM
Aaron
View paste
I have a RecyclerView in AllPostsFragment being supplied by PostsAdapter. The data model is supplied by Gson/Retrofit. Whenever the user clicks a row in the RV, a detail view fragment is kicked off, and the Reddit post ID associated with that row is added to a Room database, to track posts that have already been clicked, so I can strike thru their text. Check onBindViewHolder, and note that the text coloring is just to easily show which rows are being formatted. My problem is, when the user goes BACK from the detail view fragment to AllPostsFragment, the formatting is not always applied right away. Even though the RV, adapter, and all ViewHolders are (should be?) being recreated from scratch as AllPostsFragment comes back from the backstack. Scrolling up and down in the RV causes the formatting to be applied. But I'm totally baffled why it's only applied seemingly when the rows are recycled again...since all the objects are brand new instances. 


https://github.com/ajh3/NoSurfForReddit/blob/master/app/src/main/java/com/aaronhalbert/nosurfforreddit/fragments/AllPostsFragment.java

https://github.com/ajh3/NoSurfForReddit/blob/master/app/src/main/java/com/aaronhalbert/nosurfforreddit
...
I have a few other easy ones but this is the priority for today
Mark M.
"Even though the RV, adapter, and all ViewHolders are (should be?) being recreated from scratch as AllPostsFragment comes back from the backstack" -- not necessarily, as it depends on the transaction
Aaron
it's a replace
4:20 PM
Mark M.
how have you determined that "all the objects are brand new instances"? are you using breakpoints and logging?
Aaron
yes, I have tried logging the objects, the RV and the adapter are new objects when going BACK to AllPostsFragment
so I am pretty confused
Also, I have verified that the IDs are being correctly written into the database
Mark M.
I would run the app in the debugger, click the RV entry to get the detail, set a breakpoint in onBindViewHolder() of PostsAdapter, then press BACk
Aaron
the ID is written, I hit BACK, and formatting still is not applied until rows are recycled
Mark M.
er, BACK
Aaron
occasionally it works as intended, which might be a hint
OK
Mark M.
I'd then specifically watch for calls to the paint logic where you are managing the strikethrough
there are three possibilities:
1. onBindViewHolder() is not being called, in which case you need to notifyDataSetChanged() or at least notify for the specific row that is affected
2. onBindViewHolder() is being called, but you are not applying the strikethrough, which implies that readPostIds perhaps does not contain what it should
4:25 PM
Mark M.
3. onBindViewHolder() is being called, and it looks like you are applying the strikethrough as expected, in which case I'd sit and scratch my chin for a while, trying to figure out why that isn't showing up on the screen :-)
Aaron
do notifyItemChanged and notifyDataSetChanged force a repaint even if the data model hasn't changed? Because the database in which I am storing the clicked post IDs is not a part of the Retrofit data model that feeds the adapter
I have tried calling these methods to no avail
Mark M.
they force a fresh call to onBindViewHolder() for whatever items you indicated (e.g., the specific item for notifyItemChanged())
which is why I'm focused on seeing what onBindViewHolder() is actually doing
Aaron
I believe I have ruled out 1 and 2, so I guess I will be using the Feynman algo for this one
OK I'll focus on that
I have a few other easy questions:
View paste
1. Is the state of an activity's or fragment's FragmentManager part of the data saved to its bundle?
2. Is a switchMap transformation of a LiveData performed synchronously or asychronously?
3. In EmPubLite there are several places in the main activity where you have methods make their call to the super implementation as a part of the return statement. What's the reason for this?]
4. What is the difference between these 2 Gradle tasks: dependencies and androidDependencies
Mark M.
1. no
2. well, the switching is synchronous, but the actual new LiveData objects themselves are usually populated asynchronously
3. allowing the superclass to do its normal work
4:30 PM
Aaron
to clarify, what is the benefit of placing it in the return statement instead of in the body of the method?
Mark M.
usually, it's because I want to return whatever the superclass normally returns
Aaron
OK easy enough
Mark M.
4. I'm not exactly certain, as I have never run androidDependencies before now
Aaron
ok, then I will not worry about it
Mark M.
my best guess, based on a quick inspection of the output, is that it is purely the list of all transitive dependencies, without showing the tree of how those transitive dependencies came about
Aaron
hmm ok
OK I'll see if I can get any new info about my strikethrough problem in the next 25 minutes or so, I'll stay logged in and post again if needed, but that's all I've got for right now
thanks!!
Mark M.
OK
it you come up with more questions, just chime in
Aaron
will do
4:45 PM
Aaron
ahh, it looks like onBindViewHolder is being called before the Room LiveData observer gets the latest list of clicked posts... not sure how I didn't pinpoint this earlier, ugh, lol
I do have 2 quick followups before I go
Mark M.
OK
Aaron
Can you elaborate on question #1. So when there is a config change and fragments are destroyed and rebuilt, where is the state to accomplish that being kept, if not in the bundle?
Mark M.
the fragment managers are retained across the configuration change
basically, there's a carefully managed static field somewhere
Aaron
OK
last question
Mark M.
actually, I should rephrase that: some carefully managed static field retains the state information used by the fragment managers
4:50 PM
Aaron
OK sounds good, I am starting to get to the point where I can answer some of these questions myself by looking at the source, but not always
last question, occasionally I would like to clear the database of clicked posts
say, once a week
what should I look into as a starting point for accomplishing that?
Mark M.
for cache clearing like that, I would check when the app starts up how long it has been since the last clear operation, then clear the data if needed before you do the "real work" with the database
you're welcome to try the various long-term periodic-work options in Android: WorkManager, JobScheduler, or AlarmManager (in decreasing order of preference)
however, the real business rule would seem to be: don't use the old clicked post data if it is older than a week
Aaron
ok I was thinking more along the lines of scheduling some task or something like that, yeah, but I guess the first option makes more sense for such a small operation
Mark M.
for that, you don't need to do work every week, if the user is not using your app
Aaron
yeah
OK, that's a good list of other options though, I'll look into the basics of each of them
Mark M.
I cover WorkManager in "Android's Architecture Components" and the other two in "The Busy Coder's Guide to Android Development"
4:55 PM
Aaron
great, thanks
that's all I've got! have a good one
Mark M.
you too!
5:00 PM
Mark M.
OK, that's a wrap for today's chat
as usual, the transcript will be posted to https://commonsware.com/office-hours/ in a bit
the next chat is Tuesday at 9am US Eastern
have a pleasant day!
Aaron
has left the room
Mark M.
turned off guest access

Thursday, September 20

 

Office Hours

People in this transcript

  • Aaron
  • Mark Murphy