Office Hours — Today, May 31

Tuesday, May 29

Mark M.
has entered the room
Mark M.
turned on guest access
May 31
9:00 AM
Paul
has entered the room
9:05 AM
Paul
Greetings.
Mark M.
hello, Paul!
how can I help you today?
Paul
It has been a while but good to talk to you again. I'm here for some Gradle help.
Mark M.
I'll see what I can do -- what's the specific problem?
Paul
Here's the basic issue: I want to configure a closure for androidExtensions for each build type. Specifically I only want to enable the variable experimental if the built type is debug. Do you know how to do that?
More precisely the variable is androidExtensions.experimental, a Boolean.
I think my problem is that I do not sufficiently understand the Gradle processing model. But it sure seems like what I want to do should be easy.
Mark M.
off the cuff: defaultConfig { androidExtensions.experimental = false } and buildTypes { debug { androidExtensions.experimental = true } }
9:10 AM
Paul
I tried that and the result appears to be that experimental is always false.
Mark M.
how are you determining that?
note that it is possible that their plugin isn't set up for per-variant configuration
Paul
I use this to control caching with respect to code coverage. When I generate the code coverage report I can see what the cache valued is and infer the setting. Clear?
Mark M.
not really, but, that's OK
Paul
If you mean the Android Kotlin plugin you might be right.
Mark M.
I mean the Android Kotlin Extensions plugin
if you use set androidExtensions.experimental = true all the time, does it work as expected (just for all build variants, not just you debug ones)?
Paul
Yes.
Mark M.
/s/you/your/
then my best guess is that it is a limitation of the plugin
but, that's just a guess
Paul
Certainly a reasonable guess.
9:15 AM
Mark M.
I seem to recall when I was working on creating Gradle plugins that I had to do stuff to ensure that I was taking different build variants into account
Paul
And I can certainly file an issue. That ought to generate some helpful response.
Mark M.
what I specifically recall was honoring build variants with respect to inputs (source files) and outputs (I was writing a code generator and needed variant-specific output dirs)
Paul
Now that you mention it, I have the same recollection.
Mark M.
I forget if I had to do extra stuff to enable per-build-variant configuration and how much I experimented with that
but, if you supply them with some Gradle scripts that reproduce the problem, they should be able to identify if it is an issue with their plugin, or if we're both forgetting how this stuff should work... :-)
Paul
Yup. I agree.
Mark M.
it's possible that they weren't expecting this value to vary by build variant -- from what I'm seeing in the docs, it feels like this is controlling support for features like @Parcelize, which probably wouldn't only be used in some build variants
Paul
Since no one is chomping at the bit for their turn let me ask you another question on architecture.
First a question: are you aware of Uncle Bob's clean code architecture?
Mark M.
yes
9:20 AM
Paul
Good, then how would you structure an Android app to fit into the circles of the Clean Code Architecture (use case ring, entity ring, etc.)
Mark M.
well, to be honest, I'm not a fan of exact adherence to that architecture
Paul
I would like to know when reading some code which ring it corresponds to.
I'm trying to decide if I am a fan or not.
Mark M.
I agree with the concept of having purer abstractions (inner circles) with platform-specific details outside of it (outer circles)
Paul
So far, not.
Mark M.
I try not to get hung up on the details of "use case" and so forth
an example of the rings would come with Room or other ORM libraries that rely on base classes or annotations
some apps would consider those to be model objects
I consider them to be more akin to DTOs (data transfer objects)
and so a clean architecture approach would have models that are independent of the persistence mechanism
if you have looked at the MVI examples in "Android's Architecture Components", ToDoModel is a pure POJO, while ToDoEntity is a Room entity
Paul
My perspective is that the architecture only has value to me if by using it, I make it easier for someone to grok if they already know the Clean Arrchitecture model.
Mark M.
ToDoEntity knows how to convert to and from ToDoModel
there are elements of that
naming conventions/package selection might help
but, IMHO, all architecture stuff sounds great on paper, then crumples when applied to reality
Paul
Naming conventions of packages certainly resonates.
9:25 AM
Paul
That's where I am now, trying to apply it to reality and coming up short so far.
Mark M.
a simple, two-layer set of rings says: core POJOs should be independent of Android concerns
the sales pitch for that is: we want to use unit tests without needing Mockito to mock the heck out of the Android SDK
so you unit test those Android-free POJOs, and in there you have as much business logic as makes sense
objects that know about Android stuff like Context and widgets and SQLite and HTTP can know about those POJOs, but the reverse is not true (POJOs know nothing about those Android-aware objects, except perhaps via interface abstractions)
Paul
This ties into another concern that I have: the separate of device connected testing and JVM testing. I would like to test both and get code coverage data for both but the Android plugin makes this very hard.
Mark M.
yes, and the plugin behavior keeps changing
in theory, what you want is possible
in practice, I don't think I have ever gotten it to work
9:30 AM
Mark M.
though I've tried
Paul
So the Clean Architecture has appeal: in that I can focus my testing per ring and try to achieve high coverage for each ring rather than in total.
Mark M.
that's kinda the way I try to think about it: separation for practical reasons that happens to be clean-ish
Paul
fwiw, I recently met an engineer who claims to have done both device and jvm testing and got a report for both but have not yet verified it. My experience is similar to yours.
combined report for both, I should say.
Mark M.
there are recipes floating about Stack Overflow IIRC, but they are for older versions of the Android Gradle Plugin
Paul
Yes, definitely.
Mark M.
it's been ~6 months since I last tried getting this working
and so it's possible there are newer, better recipes than what I was seeing
Paul
Ok, this has been helpful. I thank you for that. Any questions for me before I return to my work?
Mark M.
I can't think of any
Paul
ok, :-)
Enjoy,
9:35 AM
Paul
has left the room
9:45 AM
Ed
has entered the room
Mark M.
hello, Ed!
how can I help you today?
Ed
Good morning Mark!
how are you?
Mark M.
OK, and you?
Ed
finished my Android app
so I'm pretty happy :)
Mark M.
congratulations!
Ed
thanks for the great resources
you were a big help
Mark M.
I'm happy to be useful!
Ed
feels like college
office hours feature is a GREAT DEAL :-)
Mark M.
tell your friends! :-)
Ed
on your Exploring Android book...
one minor thing that would be worth adding... imho
App global settings
Mark M.
do you mean SharedPreferences and a preference UI?
Ed
just a trivial... change them color or something stupid... just to show folks that minor area
my 2 cents
Exploring Android is excellent
Mark M.
again, just to confirm: do you mean SharedPreferences and a preference UI?
Ed
the other book is good as well... just a lot of info
9:50 AM
Ed
yes, I think that is the name
sorry
such a newb
Mark M.
OK
Ed
but the area under 'System Settings' for each app
where each app can configure a default global setting
Mark M.
um, there isn't anything like that in standard Android
an app can have its own settings UI
an app has a page in the Settings app, but the app does not control what goes in that page
now, IIRC, Android did add an option where if you have your own settings UI, that if you set the right manifest entries, a gear icon shows up in the Settings app that will link to the app's own settings UI
but that's relatively recent
anyway, there are a few gaps between the "Exploring Android" tutorials and the EmPubLite series of tutorials in "The Busy Coder's Guide to Android Development"
SharedPreferences is one of them
I'll be adding something for that eventually
right now, this is all on hold as I pivot to deal with Android Jetpack and some amount of Kotlin
Ed
good to know... thanks for the explanation
Mark M.
so, it'll be late this year, at best, before I can add that
Ed
Kotlin feels like 'Groovy' imho
Mark M.
but, it's on the list
Ed
with a Swift type of syntax
Mark M.
Kotlin and Groovy share some syntax, and Kotlin and Swift share some syntax
Ed
I took a BigNerd Ranch bootcamp on Kotlin
9:55 AM
Ed
nice language with some neat features
LOVE extensions
Mark M.
extension functions to me are a double-edged sword
Ed
and like Groovy, they added operator overloading
Mark M.
another double-edged sword
Ed
I agree
Mark M.
in the hands of experienced developers, these things are fine
Ed
it can make the code harder to 'read'
but it reduces a ton of typing
Kotlin's built in functions for example
Mark M.
it also causes problems in knowledge transfer, as code that works in Project A does not work in Project B, because A has extensions that B lacks
Ed
I agree
I ran into the same thing with Swift
i had to convert a Swift iOS app to Android
they had added extensions to Int and a few other places
to make it easier to deal with Money
Mark M.
Ruby has a similar sort of capability, and it definitely went through the hype cycle: https://en.wikipedia.org/wiki/Hype_cycle
Ruby's situation was worse, as an interpreted language, so missing stuff doesn't show up until testing or other runtime scenarios
still, I worry that some Kotlin features are right now in "Peak of Inflated Expectations"
but, I'm just a curmudgeon
10:00 AM
Mark M.
that's a wrap for today's chat
the transcript will be posted to https://commonsware.com/office-hours/ in a bit
Ed
cheers Mark!
have a great day
Mark M.
the next chat is Saturday at 4pm US Eastern
you too!
Ed
has left the room
Mark M.
turned off guest access

Tuesday, May 29

 

Office Hours

People in this transcript

  • Ed
  • Mark Murphy
  • Paul