Office Hours Transcript: 2021-11-02
john joined
hello, john!
how can I help you today?
Hello Murphy!
I just learned about your office hours yesterday, so please forgive me if I ask about things that are too hard to answer by chat. Didn’t have time to prepare.
no worries!
I have some general questions about compose.
- Do you have a template/tutorial about how to properly use ViewModel with Composable elements by any chance?
sorry, other than my jetc.dev newsletter and a few old blog posts, I have not written anything about Compose
and I think that the answer partly depends on what else you are using (e.g., Navigation for Compose)
No problem.
fun ExampleScreen(viewModel: ExampleViewModel = viewModel()) {
the key there is: what is viewModel()
scoped to?
why is the viewModel followed by ()? I’ve seen people not use them. What is the difference?
in your code snippet, viewModel()
is a function
hence, the ()
so, the first occurrence of viewModel
is the name of the function parameter; your ExampleScreen
function would refer to viewModel
but the default is coming from a viewModel()
function – that way, for a @Preview
screen or instrumented test, you could supply your own ExampleViewModel
implementation
overall, the recommendation from Google seems to be to minimize passing Jetpack viewmodels around, or even skip Jetpack viewmodels in favor of opting out of configuration changes and just using ordinary objects as "viewmodels"
all that being said, unfortunately I have not had a lot of time to actually write Compose code in recent months, so I am a bit rusty on the interaction between the Jetpack ViewModel
and composables
I see, no worries.
Second question is about widget. I did read your answer about widget in compose but I didn’t really understand everything. Is it necessary to use an xml file to make one, or is it possible to use Compose elements to some extent?
that depends a bit on your definition of "Is it necessary to use an xml file to make one"
in the end, app widgets’ UI is created using a RemoteViews
grrigore joined
hello!
the classic way to set up that RemoteViews
involves a layout resource
(hello, grrigore! I will be with you shortly!)
john: Google is coming out with a library called Glance that, among other things, allows you to define that RemoteViews
using composables
Oh, that’s good.
however, while the API will bear some resemblance to what you see with Compose for Android, Glance is really building a RemoteViews
, not doing arbitrary stuff
so, for example, Glance is not going to give you a TextField()
, because there is no support for that in RemoteViews
FWIW, I cover this more at https://jetc.dev/issues/083#and-one-more-thing
john: let me take a question from ggrigore, and I will return to you in a bit
I basically started learning Android with Compose so I don’t know the old way with the xml layouts.
Sure
thank you.
ggrigore: how can I help you today?
long story short… I have a service and I need to create a queue of items inside it
I think I might have misunderstood onStartCommand and onCreate
onCreate()
is called once; onStartCommand()
is called once per startService()
call
so let’s say there is a list inside my service myList
and I need to run something for each item that is in myList
I think I should init myList in onCreate and then append to myList using onStartCommand, right?
you would only append to myList
if the details of an item to be worked on is coming in an Intent
from startService()
yes
but, if that is indeed the case, then sure, you could do what you describe there
all good, but there’s a but :D
now that I have myList
for each item in it I need to run some API requests and a method (call it aMethod) that can only be called once
so if aMethod is called I need to wait for it to complete for 1st item in myList
before calling aMethod for the 2nd item in myList and so on
I’ve tried to achieve this using RxJava but I don’t know if RxJava it’s the best approach
well, if the rest of your app is using RxJava, sticking with it seems reasonable
so the flow would be like this
for each item in myList
call method 1 - API request
call method 2 - API request
call method 3 - this needs to complete before calling it again
call method 4 - - API request
so the flow would be like this
for each item in myList
call method 1 - API request
call method 2 - API request
call method 3 - this needs to complete before calling it again
call method 4 - API request
sorry for the double message
this chat interface is a bit weird; I have done that too
:D
I think it’s better if I post a detailed question on the forum
as I am aware what I say here might be confusing
agreed – this is probably easier in that sort of setting
another shot question if you don’t mind
is it possible to monitor a service state? a service that I start
what do you consider "service state" to be?
I’d like to know when it’s stopped
but, what would like to know when it’s stopped? basically, what is doing the observing?
so the service it’s supposed to print something. and there are cases where I need to call it more than one time
but if I start it twice the printing stops (library issue)
so I’m trying to find a way to do something like this
if service is running wait for it to complete
if service is not running take the next element in myList and start it
I guess these are called nasty hacks :D
I would try to focus more on wrapping your library usage in a Mutex
or something, to prevent parallel requests to it
alternatively, put all the synchronization logic into the service; clients calling startService()
should neither know nor care whether the service is or is not running
(in large part because they can’t reliably know whether the service is or is not running)
the problem is that when it gets to call print()
twice as in the previous print() it’s not completed
it stops printing
what is calling print()
? is it the service, or something triggered by the service?
the print() method it’s in the service
I get the image from the server using an API request and then call print()
then the service has the responsibility to only call print()
once at a time – that is not the job of whoever is starting the service
true
I mean this is a valid case too
there might be another one to treat but right now this is the one that’s causing the printing to stop
let me take another question from john, and I’ll try to get back to you a bit later
sure
@john: over to you! do you have another question?
I do but I’d need to show you my code. Is better to ask in the community forum?
the forum is better for long-form stuff, with the downside that the interaction is slower by nature
posting short code snippets here is reasonable; posting several classes’ worth of code is probably better for the forum
Got you, I’ll try the forum.
Are you planning to update your books with Compose tutorial by any chance?
um, well, the Warescription program is ending in about two months: https://commonsware.com/blog/2021/09/25/turning-the-page.html
Yes, that’s why I was asking.
my chance to say again that for me it was the best thing on android
:D
john: no, I do not plan on covering Compose – that can’t be done in just a short chapter or something
Yes, I wish I had known about it much sooner.
also Mark if you don’t mind, do you know people that are doing trainings on android?
Oh, OK I read the blog post.
ggrigore: if you mean live in-person training, AFAIK Big Nerd Ranch still offers courses in the US, and I do not know who else offers courses, particularly outside of the US
thank you
john: basically, I concluded that I either needed to do Compose seriously or not at all, and "not at all" won
I understand how you feel.
Totally agree with your philosophy.
All the best Mark. Good bye.
john left
quick RxJava question? :D
fire away!
so remember myList
and that method I need to wait for it to complete
right now I’m using an observable Observable.fromIterable(myList)
is there a way to pause it?
not that I know of, short of ending it by disposing of the Disposable
to single-thread that particular call, though, you could switch schedulers before/after it in your Rx chain AFAIK
the thing is I need to process one item at a time
get 1st one process it, done processing the 1st one, continue with the 2nd one
that is a matter of using a single-threaded Scheduler
(e.g,. Schedulers.single()
)
but no parallel stuff
I’ve tried that too but maybe I did miss something
trocchietto_ivano joined
Hallo Mark and grrigore
grrigore: I am more concerned about fromIterable()
, in that it shuts down when you reach the end of the list – that’s not designed for mutable lists
@Ivano: hi! how can I help you today, in the remaining ~9 minutes of the chat?
thanks, Mark! I’ll let you talk to ivano. maybe i’ll post the question on the forum
Hi Mark
have a nice day!
@ggrigore you too!
grrigore left
Ivano: do you have a question?
I got an adapter written really bad with more than 20 getItemViewType conditions, and is the worse spaghetti ever seen, and said from an Italian… what is defintetely worse is that is written in Scala with an old scala android library. The point is that i need to just add an header, and was wondering if I can inflate a layout using the header decoration feature
this is for a ListView
?
no a recyclerview
is the header supposed to be fixed at the top, or is it just the first item in a long scrolling list?
is just the first item in a long scrolling listg
you could use ConcatAdapter
: https://developer.android.com/reference/androidx/recyclerview/widget/ConcatAdapter
thanks I am definetely lookinto
never heard about that
create a trivial adapter for your header, then use ConcatAdapter
to concatenate your trivial adapter with your really huge one
I will try thanks
ps do you know if I can abilitate sounds in this chat?
there is a sidebar on the right that lets you control sound notifications
thanks
have a nice day
but AFAIK it only dings when you use @trocchietto_ivano notation
ah that s why
never mind
it is not as nice as Campfire was in that regard
grrigore joined
yes but the darkness of the chat is awesome
grrigore left
looks as using emacs
yes, theme control and Markdown support are nice
dark is really important when one is always behind a screen
well I go to learn about ConcatAdapter that the new job is a lot of learning but also a challenge continous against the time
:(
have a nice rest of the day in Pennsylvania or so
you too!
thanks
(minus the Pennsylvania part)
(since I don’t think you live here 😁)
ahah