Mark M. | has entered the room |
Mark M. | turned on guest access |
May 31 | 9:00 AM |
Paul | has entered the room |
May 31 | 9:05 AM |
Paul |
Greetings.
|
Mark M. |
hello, Paul!
|
Mark M. |
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?
|
Paul |
More precisely the variable is androidExtensions.experimental, a Boolean.
|
Paul |
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 } }
|
May 31 | 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?
|
Mark M. |
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
|
Mark M. |
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/
|
Mark M. |
then my best guess is that it is a limitation of the plugin
|
Mark M. |
but, that's just a guess
|
Paul |
Certainly a reasonable guess.
|
May 31 | 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
|
Mark M. |
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.
|
Paul |
First a question: are you aware of Uncle Bob's clean code architecture?
|
Mark M. |
yes
|
May 31 | 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.
|
Paul |
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
|
Mark M. |
an example of the rings would come with Room or other ORM libraries that rely on base classes or annotations
|
Mark M. |
some apps would consider those to be model objects
|
Mark M. |
I consider them to be more akin to DTOs (data transfer objects)
|
Mark M. |
and so a clean architecture approach would have models that are independent of the persistence mechanism
|
Mark M. |
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
|
Mark M. |
there are elements of that
|
Mark M. |
naming conventions/package selection might help
|
Mark M. |
but, IMHO, all architecture stuff sounds great on paper, then crumples when applied to reality
|
Paul |
Naming conventions of packages certainly resonates.
|
May 31 | 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
|
Mark M. |
the sales pitch for that is: we want to use unit tests without needing Mockito to mock the heck out of the Android SDK
|
Mark M. |
so you unit test those Android-free POJOs, and in there you have as much business logic as makes sense
|
Mark M. |
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
|
Mark M. |
in theory, what you want is possible
|
Mark M. |
in practice, I don't think I have ever gotten it to work
|
May 31 | 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.
|
Paul |
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
|
Mark M. |
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, :-)
|
Paul |
Enjoy,
|
May 31 | 9:35 AM |
Paul | has left the room |
May 31 | 9:45 AM |
Ed | has entered the room |
Mark M. |
hello, Ed!
|
Mark M. |
how can I help you today?
|
Ed |
Good morning Mark!
|
Ed |
how are you?
|
Mark M. |
OK, and you?
|
Ed |
finished my Android app
|
Ed |
so I'm pretty happy :)
|
Mark M. |
congratulations!
|
Ed |
thanks for the great resources
|
Ed |
you were a big help
|
Mark M. |
I'm happy to be useful!
|
Ed |
feels like college
|
Ed |
office hours feature is a GREAT DEAL :-)
|
Mark M. |
tell your friends! :-)
|
Ed |
on your Exploring Android book...
|
Ed |
one minor thing that would be worth adding... imho
|
Ed |
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
|
Ed |
my 2 cents
|
Ed |
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
|
May 31 | 9:50 AM |
Ed |
yes, I think that is the name
|
Ed |
sorry
|
Ed |
such a newb
|
Mark M. |
OK
|
Ed |
but the area under 'System Settings' for each app
|
Ed |
where each app can configure a default global setting
|
Mark M. |
um, there isn't anything like that in standard Android
|
Mark M. |
an app can have its own settings UI
|
Mark M. |
an app has a page in the Settings app, but the app does not control what goes in that page
|
Mark M. |
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
|
Mark M. |
but that's relatively recent
|
Mark M. |
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"
|
Mark M. |
SharedPreferences is one of them
|
Mark M. |
I'll be adding something for that eventually
|
Mark M. |
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
|
May 31 | 9:55 AM |
Ed |
nice language with some neat features
|
Ed |
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'
|
Ed |
but it reduces a ton of typing
|
Ed |
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
|
Ed |
I ran into the same thing with Swift
|
Ed |
i had to convert a Swift iOS app to Android
|
Ed |
they had added extensions to Int and a few other places
|
Ed |
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
|
Mark M. |
Ruby's situation was worse, as an interpreted language, so missing stuff doesn't show up until testing or other runtime scenarios
|
Mark M. |
still, I worry that some Kotlin features are right now in "Peak of Inflated Expectations"
|
Mark M. |
but, I'm just a curmudgeon
|
May 31 | 10:00 AM |
Mark M. |
that's a wrap for today's chat
|
Mark M. |
the transcript will be posted to https://commonsware.com/office-hours/ in a bit
|
Ed |
cheers Mark!
|
Ed |
have a great day
|
Mark M. |
the next chat is Saturday at 4pm US Eastern
|
Mark M. |
you too!
|
Ed | has left the room |
Mark M. | turned off guest access |