Office Hours — Today, April 30

Tuesday, April 28

Apr 30
8:20 AM
Mark M.
has entered the room
Mark M.
turned on guest access
8:30 AM
hemanparbhakar
has entered the room
hemanparbhakar
Hello
Mark M.
hello, hemanparbhakar!
how can I help you today?
hemanparbhakar
I have one query regarding coroutine and room
what will be the best approach if i want to insert data in room db after every 100ms
Kai H.
has entered the room
Kai H.
Hello
Mark M.
personally, I would try not to do disk I/O that frequently
(hello, Kai! I will be with you shortly!)
hemanparbhakar
ok
i am now taking the data and storing it in an array after some time i m using coroutine and insert all the data into room in single go is that a good approach ?
Mark M.
it sounds better than every 100ms, but it would depend a lot on whether the app is in the foreground or not
basically, you do not want to lose data when your process terminates
hemanparbhakar
its running service
Mark M.
so, presumably it is a foreground service, since background services do not live very long on Android 8.0+
8:35 AM
Mark M.
if there is some real-world event that is tied to your data creation, that is less frequent than every 100ms, you might save your data when those events occur
otherwise, a periodic flush of your cached data to disk is reasonable, but I'd aim for something more like every 10 seconds rather than every 100ms
hemanparbhakar
yes foreground service i am using
Mark M.
in terms of doing that sort of periodic work, coroutines on its own will not help, unless I am forgetting an option on Flow for automatically setting up a periodic task
hemanparbhakar
so instead of coroutine uisng you suggest to use flow
Mark M.
I was referring to the Flow that is part of coroutines
if you could go longer -- say, every 15 minutes or so -- WorkManager would be a solution, and there is a CoroutineScope that you can use from your Worker to call suspend functions on your Room DAO
hemanparbhakar
CoroutineScope(Dispatchers.IO).launch
using this coroutine i m performing operation
Mark M.
and that is fine, though Room will provide its own dispatcher
in terms of triggering that launch() call every so often, you will need to do something outside of coroutines, AFAIK
hemanparbhakar
so what would be that ?
Mark M.
ScheduledExecutorService would be the most likely choice if you need something more frequent than what WorkManager supports
8:40 AM
Mark M.
unlike RxJava, which has built-in periodic options for things like Observable, coroutines does not, unless there is something that I am forgetting
hemanparbhakar
ScheduledExecutorService is good ?
Mark M.
for periodic work in an already-running process, yes
in your case, you have a foreground service, so an in-process solution should be fine
hemanparbhakar
but i am using timer to call after every 10 seconds
Mark M.
personally, I am a bigger fan of ScheduledExecutorService than Timer/TimerTask, but you are welcome to use either
hemanparbhakar
ok thanks
Mark M.
let me take a question from Kai, and I will come back to you in a bit
Kai: your turn! how can I help you today?
hemanparbhakar
ok
Kai H.
When wanting Dialogs in your App(s), do you have a hierarchy of Dialog classes or do you just do them "ad hoc"?
8:45 AM
Mark M.
I tend to use DialogFragment, and ideally I don't have enough that a class hierarchy is needed
in particular, I tend towards DialogFragment classes that handle certain presentation styles, rather than ones tied to specific business logic
Kai H.
We have quite a few, some from DialogFragment, others from AlertDialog, and it's quite confusing imo.
So you want to display a list and have a dialog for that?
And then use it where the business logic requires something in list form?
Mark M.
I almost never do that -- if it is a list, it probably should be a regular-size screen (fragment or activity)
IMHO, dialogs are for things that have to interrupt the user and tend to be fairly small
Kai H.
We have a dialog to choose a user from, for example. Or a dialog to choose a file from the file system.
Mark M.
I doubt that I would do either of those as dialogs
but, that's my preferred UI/UX approach, and that of my clients
if you're going down that sort of "dialog all the things" UI/UX approach, you are more likely going to need some sort of class hierarchy to keep the code manageable
but, that's more of a gut instinct, and the details would certainly vary by project
8:50 AM
Kai H.
I see.
I noticed that the result of a dialog is often passed by callback. Is that still the preferred way nowadays?
Mark M.
nowadays, I would try to use shared viewmodels
Kai H.
I was thinking as much, especially if DialogFragment is extensively used.
Mark M.
agreed: callbacks and DialogFragment do not play well together, as you lose the callbacks on a configuration change
let me take another question from hemanparbhakar, and I will be back with you shortly
hemanparbhakar: back to you! do you have another question?
Kai H.
Sure
hemanparbhakar
yes
how to prevent memory leaks in android
and if there are any how to handle them in Profile
Mark M.
that is well beyond the scope of what I can cover in this chat
hemanparbhakar
Profiler is too confusing
so /
?
Mark M.
I have a chapter or two on memory leaks in *The Busy Coder's Guide to Android Development*
personally, I primarily focus on integrating LeakCanary
8:55 AM
Mark M.
as that does a nice job of yelling at you when you leak UI elements
8:55 AM
Mark M.
beyond that, think through all of your singletons and other static data and make sure that they cannot grow indefinitely
so, overall, I recommend that you review those chapters, and if you have more specific questions, I can try to answer those in some future chat
hemanparbhakar
ok
Mark M.
let me switch back to Kai, and I'll return to you in a bit
Kai: back to you! do you have another question?
Kai H.
Yes
Any pointers on how to best conntect a ViewModel to a Dialog?
9:00 AM
Kai H.
Like won't I be making a lot of custom Dialogs that are only used in one place?
While I could be making reusable ones
Mark M.
well, that's a bit like asking if you will be making a lot of custom activities/fragments :-)
Kai H.
Current Example would be a Dialog with a Title, a Description and an Inputfield (EditText)
Mark M.
if you want a general-purpose dialog like that, you will create a matching general-purpose viewmodel
so, if we have an SimpleInputDialogFragment, we have a SimpleInputViewModel
Kai H.
And then I share the SimpleInputViewModel with the ComplexFormularFragment
Mark M.
yes
where the SimpleInputViewModel has a LiveData<SimpleInputResult> or something, where SimpleInputResult tells you if the dialog was accepted or cancelled, and what the contents of the EditText were
Kai H.
And I guess that would be a Sealed Class if one was using Kotlin
Mark M.
yes
9:05 AM
Mark M.
alternatively, you could just have a single SimpleInputResult with a status field (such an wasAccepted boolean) and a field with the EditText contents
Kai H.
About LiveData: I would get the SimpleInputViewModel in my ComplexFormularFragment and observe the SimpleInputResult from SimpleInputViewModel?
I am still not sure how LiveData works ;-)
Mark M.
yes
let me switch back to hemanparbhakar, and I will come back to you later
hemanparbhakar: your turn! do you have another question?
hemanparbhakar
what the differences between when we intialize Alertdialog(this) and Alertdialog(getApplicationContext())
Mark M.
do not do the second one
hemanparbhakar
y so ?
Mark M.
when it comes to UI stuff, always use the activity as the Context
Application does not know anything about themes
hemanparbhakar
reason ?
Mark M.
whereas Activity does
hemanparbhakar
ok so always to this right ?
Mark M.
yes: if you are showing a dialog, use the activity as the Context
using the Application as the Context for things like file I/O (getFilesDir()) or even getting at string resources is fine
but anything that might be affected by styles and themes needs to use an activity that has those styles and themes
9:10 AM
hemanparbhakar
ok
Mark M.
let me take another question from Kai
Kai: back to you! do you have another question?
hemanparbhakar
has left the room
Kai H.
Let's say you have a form and that needs a user. How would you go about picking one from a list of users?
Mark M.
choose the user before showing the form, probably
IOW, use more of a wizard style than a window-and-dialogs style
9:15 AM
Mark M.
if the form has to be presented first, then I would have the choose-a-user button bring up a regular-size fragment, even if it happens to be wrapped in a DialogFragment for control flow
IOW, there is "dialog as a small window" and "dialog as an interrupt to the existing screen", which aren't strictly tied
Kai H.
So as much full screen as possible?
Mark M.
yes, because not everyone has large phones
wasting screen space for a dialog aesthetic IMHO isn't user-friendly
Kai H.
So I guess quite a few of our Dialogs would be Fragments if it was your app
Like the "select file dialog" and "select user dialog"
9:20 AM
Mark M.
if those are true "small window" dialogs, then yes
but, bear in mind that most of the time, I'm not the one coming up with the UI designs -- professional designers are
most of *them* only use small-window dialogs for simple messages and confirmations
(at least, of the designers that I have worked with)
and so to an extent I have adopted their design patterns
Kai H.
We have Dialogs with Tabs in them, for folder selection for example :D
Mark M.
yeah, I'm not a fan
Kai H.
thanks for the input, I guess I have some more to think about now
Our BaseDialog class that extends DialogFragment has callbacks in them btw. I wonder how or rather why it works :D
9:25 AM
Mark M.
if your development team is like many development teams, they don't think about configuration changes much :-(
for example... does your app support landscape?
Kai H.
It saves two DialogInterface.on*Listeners
It actually does
Which makes me wonder why it works.
Mark M.
then make sure you test those DialogFragments where you display them, then rotate the screen
the activity (or parent fragment) displaying the DialogFragment needs to know to reconnect any callbacks after the configuration change
Kai H.
Test those? You mean test them by rotating the screen or write tests for them?
Mark M.
I'd settle for "test them by rotating the screen"
Kai H.
Maybe that is how it's done, that the Fragment reconnects
Mark M.
that's certainly doable, but it's easy to forget
part of the advantage of the ViewModel+LiveData approach is that getting the core functionality to work also covers you for configuration changes
Kai H.
I think I really like the idea of having my ViewModel in my Dialogs
I guess it would make quite a few things easier
Mark M.
personally, I think of it less of "easier" and more of "more likely to do the right thing in more scenarios"
9:30 AM
Kai H.
Well, yes
Mark M.
if it happens to be less typing or otherwise easier, that's a nice side benefit :-()
Kai H.
"Easier" in "less to forget and less places to look at"
Mark M.
(sorry, that was :-) with an emoticon typo...)
right
Kai H.
I am lazy and forgetful, so I need to make things "simple"
Mark M.
and that's all the time I have for now, so that's a wrap for today's chat
the next one is Saturday at 4pm US Eastern
have a pleasant day, and stay healthy!
Kai H.
Same
Kai H.
has left the room
Mark M.
turned off guest access

Tuesday, April 28

 

Office Hours

People in this transcript

  • hemanparbhakar
  • Kai Hatje
  • Mark Murphy