Disclaimer: I always try to attend case-study sessions or panels if possible and not hardcore coding ones (personal taste, I prefer to watch coding ones at home at my own speed, or even better read that content as articles).
My favorite talks (based on ones that I have seen)
- Inside the .git folder - Explore the mysterious depths...
by Benjamin Kadel
- SDK Design and Publishing For Kotlin Multiplatform Mobile
by Kevin Galligan
- Sharing code among multiple projects: the case of internal libraries
by Jean-Baptiste Vincey - also kudos for a great discussion after the talk!
- Deep dive into Modern Android Performance
by Ben Weiss and Tomáš Mlynarič
- Lessons Learned Migrating the Maps SDK to Compose
by Chris Arriola
Takeaways for me
- Create a sample repository with a demo app in our company, something like 'Now in Android' but following patterns and tools that we use.
- to have an easy onboarding for new joiners (ex. a coding lab to do on this demo project) and get familiar with how to commit, get familiar with CI/CD etc.
- To allow easy discussion about improvements to our approach for developers.
- Possibility to share it publicly. Something like Freeletics MAD.
- Allows to share our knowledge with others and get feedback.
- Candidates know much better what to expect.
- Align between many internal teams/projects on a common approach and have a common ground (as we have a goal to have the same tech stack/patterns across our apps).
- A surprisingly small number of teams is doing Compose-only projects, in most cases, it is a mix, and Fragments are still heavily used as a middle ground.
- Google's opinionated approach with Google Jetpack is working well and it is everywhere, at this point there is no escape? I haven't seen anybody prising Fragments, Redux, or MVP... It is a bit sad on one end and on the other it simplifies a lot.
- It seems like bigger codebases are already in hundred of Gradle modules. Are we going too far? So far so good but I just wonder when it should be a warning sign.
So let's dive deep into what I have seen on Droidcon and my opinions on particular presentations and panels. This is my private opinion and I do believe it can really vary from person to person even for the same talk, and there is nothing wrong with this.
Day 1 (06.07.2022)
Keynote: Now in Modern Android
It was a perfect intro to Jetpack and to give a clear vision of why Google created more opinionated tools and patterns, as well as to mention many topics for the next couple of days (testing, architecture...) and double underline that Kotlin+Compose+Jetpack is the future. I always prefer more 'light' keynotes - ex. on Droidcon Berlin in 2018 there was Gitlab VP of Product (Job van der Voort) with "best apps are build in pyjama-pants" a perfect segway into remote-only work (in 2018!) by Gitlab, interesting and light, a perfect keynote.
New to me were Gradle Convention Plugins to reuse much of Gradle config between multiple Gradle modules, and a good reminder that we can already use Gradle Version Catalog.
Crash-reporting taken to next-level
Delivery Hero talk about utilizing Google Firebase Crashlytics in a company with many apps, many teams as well multiple countries. #scale
They use Google Data Studio to create custom internal dashboards to easily filter data that is needed from Google BigQuery, and build on top of Crashlytics. Also that you can use some other tool (ex. Apache Airflow) to enrich/pre-process data so it is more useful and load it back to Google BigQuery.
The minor but neat part was to have the option to enforce on clients to update app not only "above" specific app version but also for a very specific one (ex. users with app below 2.10.3 needs to update to use app, but also 2.14.0 needs to update as it had a major bug).
I have mixed feelings about the author's approach to monitor last seen screen and use that information to automatically assigns crashes to a team in Delivery Hero, and monitor for work quality. I also have a bit of a feeling some mentioned features would be much easier to do in Sentry, ex. adding tags to see if the issue is happening only in a few countries or everywhere (authors had checked it but it didn't meet their requirements - I think the price was mentioned as a factor).
Inside the .git folder - Explore the mysterious depths...
Ben Kadel show - a mix of standup, cave exploration and great developer knowledge about git internal files and how they work. Words won't do justice to it so here is a brief video, my take: if you have an option to attend Ben's talk at any other conference, just do it.
Is my application taking up too much power?
What's new in Apollo Kotlin 3
Interesting talk about some choices and issues of Apollo library creators when they decided to do Apollo 3.X SDK focused on Kotlin.
Very interesting was an issue with codegen that the team initially struggle with (it was generating in some cases much more Kotlin code than schema itself), and team took a decision to give this feature (responseBase) as a opt-in feature.
New to me: @nonnull annotation in operations to generate better Kotlin code, and declarative cache.
SDK Design and Publishing For Kotlin Multiplatform Mobile
I haven't used KMM on a production scale so it was my go-to session, especially as it was by Touchlabs and a bit more from an iOS perspective. Also are we saying KMM or KMP?
At the moment it a bit painful to use all features in Swift from KMM module as there is ObjC layer in the middle as well KMM itself has some limitations still (ex. enums, sealed classes, optional parameters, Kotlin Flow and Coroutines are a bit tricky).
Currently there are some workarounds for most of those issues, many of them leads to having additional layer of abstraction between KMM module and iOS application (not great). But there is work being done to enable Swift Generation Library, there was a (almost) working demo and we can expect more being announced in September 2022 on Droidcon NY. Fingers crossed for this one.
Concurrency for Imposters
We should be able to say "I don't know and I would like to spend some time to understand XYZ". Do not treat others from a top of a mountain and help others to also understand some complex solution (ex. Rx or Coroutines).
I was expecting more from a technical perspective on Kotlin Coroutines, and it only briefly mentioned Context vs. Scope.
Modern Testing on Android
Very well prepared Google presentation about testing - why and how. It started with a short scene of manual testing struggles and smoothly moved into tools that we should be using (most of them from Google) to address different types of testing.
Also a subtle note that you can notice to appear as a pattern in many talks about testing: Compose is much better in that aspect and if you don't use Compose you will be staying behind soon, also in the area of testing.
De-mock your tests
TLDR: Use Test Doubles. I think most of content is in the article from the same author. I prefer to read/watch such presentations at home so I switched rooms during this time slot few times to see what else is interesting.
Orchestrate your UI tests with Conductor
Presentation of a tool called Conductor for recording and replaying network traffic with mitmproxy. Looks ok-ish - I cannot find URL to the tool itself however, also I think most of ex. Charles Proxy or Proxyman have that built-in to some extent and if you are more advanced you can use MockLab (or self-host it) for the same functionality. I guess "it depends" based on your team's needs and constraints.
Implementing a Design System in Compose
I only briefly attended this talk. It was very very entry-level for those who do not yet use the design system, especially in Compose. I also believe a better starting point would be taking a peek at how Google is doing theming/styling in Material Design and go from there.
Modern Android Development (panel)
Googlers answering questions from the public - mostly about M.A.D. Bulletpoints:
- Google is looking into lowering entry barrier for screenshot testing - especially with Compose. Looking into helping authors of ex. Paparazzi, Showkase, Shot and others, or just maybe creating their own tool if they would see a need for it.
- SafeArgs in Navigation Compose - not yet, not on a close roadmap, no comment.
- Baseline profiles - this was underlined over different talks and on a panel as well, start using it now, also for SDKs.
- Text styling from HTML - not available in Compose, maybe in the future.
- Guidelines are here to help and not to enforce. They should give an easier and better starting point but if you want to do it differently - it is totally ok (the question was about Channels vs. Unidirectional Data Flow).
Day 2 (07.07.2022)
On day 2 there were moments when I would like to be in all rooms at once. Those are problems that it is good to have.
Deep dive into Modern Android Performance
Good talk about using proper tools to monitor app performance also on production. Keypoints: JankStats and micro and macro benchmarking for app performance. On a CI/CD consider using a sliding window algorithm to detect regression as it is tricky. Google official repo with performance samples, worth checking.
Untangling Coroutine Testing
Márton Braun has posted his slides online and I really recommend going through them. Also Google Coroutine testing guide, and Kotlin Flows testing guide were recently updated. For the Flow you also might consider utilizing Turbine library.
Writing bulletproof code with property-based testing
Implementing Modern Android Architecture
For this one room was packed so people were standing in the back. Very good presentation on the key points of M.A.D. architecture from Google, at least to be aware of what and why Google is recommending. It is based on Google guide to architecture, sample arch repo, codelab on architecture. Manuel Vivo posted on Twitter a summary of this talk.
Due to full room and technical issues (clicker related) presentation was repeated in the afternoon once again - once again a full room!
Sharing code among multiple projects: the case of internal libraries
A case study from Deezer! I love those and I really enjoyed this presentation. A good walkthrough on team decisions and rationale behind - how Deezer is sharing core libraries between multiple apps and different teams. Takeaways:
- Keeping library design, core and features in separate repositories was too much of overhead
- ~3 libraries shared among company
- Later on Deezer moved to one repository and just different modules for Design, Features, and Core for each library (ex. Authorization) so it is versioned and bundled together always and can share some scripts or gradle dependencies.
- Release train - each 2 weeks (same as the app). Major.Minor.Patch naming.
- A lot of additional tooling - sample app for each library, documentation (static website using MkDocs), scripts to build and deploy locally
- Core team to maintain and develop those shared libs then app and feature teams.
- Pair coding is encouraged between people from the core and feature teams to share knowledge and spot-on pain points.
- Fixing bugs is still a challenge.
- DI is not used in shared libs as different apps can have different DI (Hilt/Koin) so a simple Service Locator pattern is used, a bit tricky and some questions remained unanswered around this topic as it is more complex.
- Each shared lib is published as a collection of Gradle modules (ex. there are Kotlin-only modules so in the future migration to KMM is easy). They are published always at once with the same version.
- Around 100-200 Gradle modules across apps, and KMM is already used in core library (if I understood this correctly).
- iOS is working a bit differently as it uses git submodules.
- Each app-team adopts core-lib changes at its own pace.
Common Traps You Can Step Into When Using Coroutines
A talk by known YouTuber Philipp Lackner. I wasn't there, the room was packed, but I heard good opinions (but it was short, is this even a disadvantage?), I look forward to watching this on YT.
Android Benchmarking and other stories
I got a feeling this was very overlapping with the previous talk "Deep dive into Modern Android Performance" - JankStats, Micro/Macro benchmarking, using CI/CD to monitor for performance regression. I think out of those two I would recommend watching the "Deep dive into Modern Android Performance" as it was more brief and on point to me.
Lessons Learned Migrating the Maps SDK to Compose
Another case-study! And I also enjoyed that one. A developer from the Google Maps SDK team (now in Compose team) was sharing decisions and key aspects when they ported Maps SDK to Compose. Basically, it has to be AndroidView (for now), but they created a giant wrapper for it to ensure interoperability with Compose and a good SDK interface. I really keep my finger crossed for true Compose-only Map SDK soon as currently there are still not all features in the wrapper available in Compose-way (ex. CameraPositionState, Maps Utils, or local map styling, all require workarounds). Key takeaways:
- Declarative usage where possible (ex. Markers where possible but not CameraPosition) -> Compose mental model
- Reuse as much as possible and stay familiar with previous Maps API
- Utilize Kotlin features: Coroutines, Trailing lambdas, default parameters...
- Follow Compose guidelines
- Provide escape-hatch - so if somebody needs a missing feature there is an option to do it (ex. MapEffect)
- Some parameters shouldn't trigger recomposition - they should be passed in Factory (googleMapOptionsFactory)
Scaling Productivity: How we have improved our dev experience
One more case study! Decent one but most of the takeaways shouldn't be blindly taken as "it depends" (on your team size/structure and company, product, and current state... and probably dozens of other factors).
Freeletics also published the basics of their patterns as a public repository.
- Freeletics team is around 15 Android developers, and multiple feature teams (with a backend).
- Very large codebase and many smaller apps despite client-facing product simplicity, around 600 Gradle modules.
- They measure OKRs: PR review time, Rework rate/ Num of bugs, Repetitive tasks, time to onboard new joiners, time to create a new mobile release, build times / CI costs.
- Custom architecture - state machine, Unidirectional Data Flow, Dagger+Anvil, Compose for new features, Fragments as parts of app still don't have Compose.
- They had a lot of manual work when creating new Gradle module (binding StateMachine to Navigator to Composable and Fragment) -> solution was to create a script to automatize code generation for basic classes -> a new problem: lifecycle issues in Fragment
- Next solution iteration: pre-created Fragment to ensure proper binding -> a new problem: doesn't scale, a lot of manual code generated in hundreds of modules, developers doing hacky workarounds.
- Next solution iteration: Annotation-based code generation to bind Fragment with StateMachine and Compose. Easy to update generated code, only using ComposeScreen for one of the app which is fully Compose.
- Team takeaways: start with a simple task and iterate based on developer's feedback, in this case, codegen from annotation worked well.
- The second part was about the different problem - related to navigation as it didn't scale well, and had issues with SafeArgs due to circular dependencies. In this case, codegen wasn't a solution but creating two navigation elements was (destination and screen that navigates from it - if I got it correctly)
Day 3 (08.07.2022)
Comedy Talk - Better Android Development (BAD)
This talk had everything, doesn't matter if you are just starting with Android or you think you know everything. Best coding patterns, self-certification, and a portable shrine to make your code work.
Explained: Compose Compiler and Runtime
Nice talk about how Compose creates a tree structure of views and updates them as well as keeps a reference to what is inside and what it relates to in code. Slides are here, also there is I think an article about a similar topic is here and of course, there is a book Jetpack Compose Internals which I recommend if you want to dive deeper. The presentation was a nice 20-minute summary on this topic which everyone should be familiar with.
Transforming farmer's lives using Android in Kenya
This app has it all: old devices, slow/bad internet connection, legacy code, offline mode, and server-driven UI. This is for sure challenging, but that the team behind this is managing with all those constraints!
How to scale a unicorn-building engineering team (and stay sane)
Speaker didn't show up :(
RoverMap: Rendering a Vector Map With Rust and Vulkan
This one was a deep dive and an interesting one. I have a soft spot for maps after dozens of days with OpenStreetMap server, as well as a local implementation of Leaflet and Google/Huawei maps so it might be due to that.
The authors briefly described how map is working (tiles), and moved to decision why they picked Rust and Vulkan as their tools to render vector map. It was due to performance (thanks LLVM), difficulty to work with (in comparison to C/C++), and cross-platform support. Worth noting: Mozilla Rust to Android Gradle plugin, , Cargo-NDK if you want to try Rust on Android. There is a code sample from the authors and more most likely will be published next year (due to university thesis).
Android at Scale (panel)
Questions and discussion was mostly about team size, structure, platform-team and feature-teams. The discussion was a decent one, I have long notes from this one and might be for a separate blog post (or one about feature teams?), but if I have to summarize: "it depends". Mostly on a number of developers but as well on product/business organization (ex. if we do one app vs. dozens of apps). It is very hard to draw a conclusion or even recommend something without knowing all details about a particular organization. As we in MODIVO are heavily discussing many things around this topic (how to organize our teams for best cooperation) it was a must-see panel for me, but as expected - there is not a silver bullet, just a number of good practices that just might also work in some other workplace.
Shooting a "Glance" at App Widgets
Then I switch rooms few times between ongoing talks and networking on corridors but I haven't found anything extraordinary for myself.
One thing to note from those 2 slots is "Why do I have more than one Application instance?" Summary is that the Application is singleton but for each Process (do not mix with Thread) which can lead to multiple usages of the same file (case of a database) and concurrent modification of it.
If you have ever seen a "Speechless" on Google I/O it is the same format :)
Improv to given slides and a topic.
👥 I had a good time (first conference in person in a long time), and met some old friends, colleagues that I have never met in person at work due to COVID but by an accident we met at Droidcon, as well as new ones 🤝.
📣 On a downside, I feel like we don't have as many heated discussions about patterns and tools as more and more of them are from single bag called "Jetpack", but maybe it is a good thing and a bring more maturity in Android Dev, as well lower entry barrier for newcomers and to avoid mistakes.
🗺 Also, such a conference is not aimed to give you expert knowledge after 40 minutes but more of a place to start, a brief understanding, and maybe some tips on what to avoid. I think it delivered on this (at least for me).
🧪 Personally, I would just prefer more case studies from different companies and fewer Google M.A.D. presentations which have a big overlap with already existing materials on YT, or maybe we should just call it Google Droidcon Berlin at this point?
See you next year? Let's see 🤔