Office Hours — Today, April 16

Tuesday, April 14

Mark M.
has entered the room
Apr 16
8:25 AM
Mark M.
turned on guest access
8:30 AM
Mohd A.
has entered the room
Mark M.
hello, Mohd!
how can I help you today?
Mohd A.
Hello Sir
Actually I have a recyclerview having cards of multiple layouts and I need to call differect Rest api on every cards. What approach should I use?
Mark M.
the cards should not be calling a REST API -- they should be showing the results from something else calling a REST API
we aim for "separation of concerns", trying to keep the UI logic as simple as possible, moving non-UI logic (such as REST API calls) elsewhere
Mohd A.
Yeah the response that will get from REST apis need to be shown in cards view.
8:35 AM
Mohd A.
But I am asking how to manage those multiple requests.
Mark M.
are you using the Google layered architecture approach? IOW, are you using ViewModel, and having it talk to repository objects that are responsible for the network I/O?
if not, what code is making the REST API calls?
Mohd A.
Yeah I am using ViewModel that would talk to repository. But I am confused should I use come kind of for loop to execute those calls?
Mark M.
probably not, though it would depend a bit on the calls
if you have N different REST calls for these cards, do you have N different functions on the repository to make those calls?
Mohd A.
Yeah all calls point to different endpoints and having different request fields.
Mark M.
in that case, a loop probably will not help
your viewmodel will just need to make those N calls, probably in N separate lines of code
the viewmodel can then make those results available to your activity/fragment
8:40 AM
Mark M.
that could be through N separate LiveData objects, or a single LiveData object representing the result of all N calls combined
Mohd A.
What good approach will be suitable to run those APIs in parallel or at same time.
?
Mark M.
that will depend a bit on how you have set up the repository API
if you are using RxJava or Kotlin coroutines, there are recipes for making that work a bit more parallel
if your repository is using callbacks and doing its own thread stuff, then the repository would be responsible for parallelism (e.g., using a thread pool)
Mohd A.
I am using coroutines but not able to figure it out to run in parallel.
Mark M.
does your repository API use suspend functions? if so, you can use async/await to do the work in parallel
Mohd A.
Yeah it is using suspend function.
Mark M.
https://klassbook.commonsware.com/lessons/Corou... shows a single async builder, with await() to find out the results
Mohd A.
Thanks for the your quick help.
8:45 AM
Mohd A.
Will try to use this.
Mark M.
if the work is being done on a multi-threaded dispatcher, such as Dispatchers.IO, then the calls may be done in parallel
Mohd A.
Sir, I am not good in threading stuff. Would you please suggest something to become expertise in threading.
Mark M.
very few people are "good in threading stuff" :-)
Mohd A.
Yeah right.
Mark M.
coroutines is a good choice for how to deal with concurrency and parallelism
Mohd A.
Okay..For that I am currently reading your written coroutine book.
Mark M.
and I apologize for not updating that recently -- my time has been taken up by other books
if you want lower-level knowledge, you could look at books on Java concurrency
the best book on that was "Java Concurrency in Practice", though it's getting a bit old, and I do not know if there is something newer that is similar
8:50 AM
Kai H.
has entered the room
Kai H.
hi
Mohd A.
No, there is no any update for this book from very long time.
Mark M.
Mohd: I hope to update it again in a couple of months
Mohd: let me take a question from Kai, and I will come back to you in a bit
Kai: hi! how can I help you today?
Kai H.
I try to add multiple Views with a custom layout to a LinearLayout
(programmatically)
The custom layout has a TextView. When I try to set the Text of the View, I always update the TextView of the first Element, not the one just added
Mark M.
you would need to hold onto all of those multiple views
or, hold onto the dynamically-generated IDs that you assign them
or, switch from your LinearLayout approach to RecyclerView
Mohd A.
has left the room
Kai H.
I guess the problem is that I have a fixed id?
8:55 AM
Mark M.
if you add N copies of a custom view to a LinearLayout, and you call findViewById() on the LinearLayout for an ID of a widget inside a custom view, you will get any of the N copies of that widget
Kai H.
TextView listItemText = listItem.findViewById(R.id.userListItemText);
Mark M.
is listItem the LinearLayout or the custom view?
Kai H.
The custom view
Mark M.
then listItem itself must be the first custom view
if you are getting the TextView from the first custom view
Kai H.
View listItem = View.inflate(getContext(), R.layout.listItem, linearLayout);
Mark M.
is TextView listItemText = listItem.findViewById(R.id.userListItemText); on the next line in your source?
Kai H.
I guess I always get the same listitem here and re-add it to the layout all the time?
Yes
Mark M.
I have not used View.inflate(), but my guess is that it is just using LayoutInflater's own inflate()
if so, View.inflate() should be creating a new custom view each time
and I cannot explain why findViewById(), on that custom view, would return a widget from outside of that custom view
Kai H.
I cannot explain it either :D
9:00 AM
Kai H.
Why only the TextView of my first custom LinearLayout view gets updated, not the one I am adding.
Mark M.
if you had TextView listItemText = linearLayout.findViewById(R.id.userListItemText); I could see behavior like that
you originally wrote "I try to add multiple Views with a custom layout to a LinearLayout" -- are you calling View.inflate() and stuff in a loop?
Kai H.
Yes, I am
The goal is to have a simple "list" without using RecyclerView or any other List, to circumvent issues with scrolling
Mark M.
your LinearLayout will still need to be in a ScrollView/NestedScrollView, otherwise it might not fit on the screen
Kai H.
It is, that is the reason for the circumvention :D
Mark M.
so I am not certain what "circumvent issues with scrolling" means and how the LinearLayout approach will help there
¯\_(ツ)_/¯
Kai H.
If I make it a List, then I don't know how to display all the entries. And there might be confusion on what to scroll
Mark M.
I'll take your word for it
9:05 AM
Kai H.
But I might end up doing it with RecyclerView eventually. It's a proof of concept right now and supposed to be held simple
Mark M.
in your loop, you might try breakpoints or Log statements to confirm the object IDs of listItem and listItemText, to see what you get
and you might try Layout Inspector to confirm that your LinearLayout is getting set up the way that you expect
Kai H.
They are always the same
Mark M.
View.inflate() is returning the same object each time?
if so, stop using View.inflate() :-)
Kai H.
Yes, it seems like it.
Mark M.
try switching to LayoutInflater directly
(preferably getting the LayoutInflater by calling getLayoutInflater() on your activity)
and see if that helps
9:10 AM
Kai H.
It actually doesn't. Huh. I still get the same views each time
Mark M.
are you using the two-parameter inflate() (i.e., inflate(R.layout.listItem, linearLayout);)
Kai H.
Yes
Mark M.
if so, try inflate(R.layout.listItem, linearLayout, false); and manually add the inflated item to the LinearLayout
(with an appropriate LinearLayout.LayoutParams)
Kai H.
Aaaand it works
(Without having added a LayoutParams)
Mark M.
LinearLayout might have a default LayoutParams that it uses
it has been years and years since I last used two-parameter inflate() methods, so I forget the rules
9:15 AM
Mark M.
I would not have expected the behavior that you were seeing, though
Kai H.
Neither would I.
Mark M.
but, at least now you have a path for moving forward
Kai H.
Thank you
I noticed I am confused by layouts ;-)
Should inflating the same layout twice give you two different objects?
Mark M.
with the three-parameter inflate(), yes
with the two-parameter inflate(), apparently not
Kai H.
Shouldn't it be intended behaviour that if you inflate a Button at different places you always get the same button?
If so, how can you have different objects with the same layout?
So many questions ;-)
Mark M.
ah, I see the problem
the two-parameter inflate() is not returning the inflated layout -- it returns the object you passed in as the root
Kai H.
I see
Mark M.
so, inflate() was returning your LinearLayout
and your findViewById() call was being made on the LinearLayout
9:20 AM
Mark M.
API Level 1 methods can be weird sometimes :-)
Kai H.
I now have my list
Should one not use them anymore?
Mark M.
if you mean methods that were introduced in API Level 1, they are unavoidable
lots of what we use was introduced back in Android 1.0
it's more that we have gotten better at API design as an industry in the intervening decade-plus
Kai H.
And now we are stuck with the old APIs?
Mark M.
they can't change them in ways that break backwards compatibility
so, the two-parameter inflate() will have a funky return value for the rest of time
sudokai
has entered the room
Mark M.
now, in some cases, the old APIs get deprecated and replaced
at which point we try to avoid the deprecated ones
9:25 AM
Mark M.
let me take a question from sudokai, and if there is time, I'll swing back to you
sudokai: hi! how can I help you today?
(in the remaining 5 minutes of the chat)
sudokai
Hi, what are the different foreground service notification types for?
Mark M.
you mean on Android 10+?
sudokai
Yes
FOREGROUND_SERVICE_TYPE_DATA_SYNC
FOREGROUND_SERVICE_TYPE_NONE
Why should I use one?
Mark M.
if so, they are kind of a quasi-permission system, in that you have to declare the foreground service type to be able to use that capability
sudokai
But take workmanager for example
Do you need to specify the type when creating the foreground info?
The example listed there does not
Mark M.
probably not, though technically it would depend on what the work does
sudokai
I'm using WorkManager to upload stuff
Mark M.
View paste
in Android 10, the list of types are: "connectedDevice" | "dataSync" |
"location" | "mediaPlayback" | "mediaProjection" |                                      "phoneCall"
now, I don't know what "dataSync" controls
sudokai
Okay
Mark M.
but, for example, if you want to use the media projection APIs to take screenshots or record screencasts, you would need to add mediaProjection as a foreground service type
sudokai
Thanks
I'll read a bit more
Back to you Kai
Mark M.
note that they added camera and something else in Android R -- I forget the second oen
er, one
sudokai
;)
Mark M.
OK, two-minute free-for-all: any last questions?
Kai H.
;-)
9:30 AM
Kai H.
I think time is up
Mark M.
yeah, that's a wrap for today's chat
the transcript will go up on https://commonsware.com/office-hours/ shortly
sudokai
No more questions from me
Thanks
Mark M.
the next chat is Saturday at 4pm US Eastern
have a pleasant day, and stay healthy!
Kai H.
Same
Kai H.
has left the room
sudokai
has left the room
Mark M.
turned off guest access

Tuesday, April 14

 

Office Hours

People in this transcript

  • Kai Hatje
  • Mark Murphy
  • Mohd Aquib
  • sudokai