Apr 30 | 8:20 AM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Apr 30 | 8:30 AM |
hemanparbhakar | has entered the room |
hemanparbhakar |
Hello
|
Mark M. |
hello, hemanparbhakar!
|
Mark M. |
how can I help you today?
|
hemanparbhakar |
I have one query regarding coroutine and room
|
hemanparbhakar |
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
|
Mark M. |
(hello, Kai! I will be with you shortly!)
|
hemanparbhakar |
ok
|
hemanparbhakar |
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
|
Mark M. |
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+
|
Apr 30 | 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
|
Mark M. |
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
|
Mark M. |
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
|
hemanparbhakar |
using this coroutine i m performing operation
|
Mark M. |
and that is fine, though Room will provide its own dispatcher
|
Mark M. |
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
|
Apr 30 | 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
|
Mark M. |
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
|
Mark M. |
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"?
|
Apr 30 | 8:45 AM |
Mark M. |
I tend to use DialogFragment, and ideally I don't have enough that a class hierarchy is needed
|
Mark M. |
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.
|
Kai H. |
So you want to display a list and have a dialog for that?
|
Kai H. |
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)
|
Mark M. |
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
|
Mark M. |
but, that's my preferred UI/UX approach, and that of my clients
|
Mark M. |
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
|
Mark M. |
but, that's more of a gut instinct, and the details would certainly vary by project
|
Apr 30 | 8:50 AM |
Kai H. |
I see.
|
Kai H. |
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
|
Mark M. |
let me take another question from hemanparbhakar, and I will be back with you shortly
|
Mark M. |
hemanparbhakar: back to you! do you have another question?
|
Kai H. |
Sure
|
hemanparbhakar |
yes
|
hemanparbhakar |
how to prevent memory leaks in android
|
hemanparbhakar |
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
|
hemanparbhakar |
so /
|
hemanparbhakar |
?
|
Mark M. |
I have a chapter or two on memory leaks in *The Busy Coder's Guide to Android Development*
|
Mark M. |
personally, I primarily focus on integrating LeakCanary
|
Apr 30 | 8:55 AM |
Mark M. |
as that does a nice job of yelling at you when you leak UI elements
|
Apr 30 | 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
|
Mark M. |
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
|
Mark M. |
Kai: back to you! do you have another question?
|
Kai H. |
Yes
|
Kai H. |
Any pointers on how to best conntect a ViewModel to a Dialog?
|
Apr 30 | 9:00 AM |
Kai H. |
Like won't I be making a lot of custom Dialogs that are only used in one place?
|
Kai H. |
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
|
Mark M. |
so, if we have an SimpleInputDialogFragment, we have a SimpleInputViewModel
|
Kai H. |
And then I share the SimpleInputViewModel with the ComplexFormularFragment
|
Mark M. |
yes
|
Mark M. |
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
|
Apr 30 | 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?
|
Kai H. |
I am still not sure how LiveData works ;-)
|
Mark M. |
yes
|
Mark M. |
let me switch back to hemanparbhakar, and I will come back to you later
|
Mark M. |
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
|
Mark M. |
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
|
Mark M. |
using the Application as the Context for things like file I/O (getFilesDir()) or even getting at string resources is fine
|
Mark M. |
but anything that might be affected by styles and themes needs to use an activity that has those styles and themes
|
Apr 30 | 9:10 AM |
hemanparbhakar |
ok
|
Mark M. |
let me take another question from Kai
|
Mark M. |
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
|
Mark M. |
IOW, use more of a wizard style than a window-and-dialogs style
|
Apr 30 | 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
|
Mark M. |
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
|
Mark M. |
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
|
Kai H. |
Like the "select file dialog" and "select user dialog"
|
Apr 30 | 9:20 AM |
Mark M. |
if those are true "small window" dialogs, then yes
|
Mark M. |
but, bear in mind that most of the time, I'm not the one coming up with the UI designs -- professional designers are
|
Mark M. |
most of *them* only use small-window dialogs for simple messages and confirmations
|
Mark M. |
(at least, of the designers that I have worked with)
|
Mark M. |
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
|
Kai H. |
Our BaseDialog class that extends DialogFragment has callbacks in them btw. I wonder how or rather why it works :D
|
Apr 30 | 9:25 AM |
Mark M. |
if your development team is like many development teams, they don't think about configuration changes much :-(
|
Mark M. |
for example... does your app support landscape?
|
Kai H. |
It saves two DialogInterface.on*Listeners
|
Kai H. |
It actually does
|
Kai H. |
Which makes me wonder why it works.
|
Mark M. |
then make sure you test those DialogFragments where you display them, then rotate the screen
|
Mark M. |
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
|
Mark M. |
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
|
Kai H. |
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"
|
Apr 30 | 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...)
|
Mark M. |
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
|
Mark M. |
the next one is Saturday at 4pm US Eastern
|
Mark M. |
have a pleasant day, and stay healthy!
|
Kai H. |
Same
|
Kai H. | has left the room |
Mark M. | turned off guest access |