Share
Embed
Transcript
24 slides
-
State of the app in March 2017 • 9M MAU
• < 1% crashes • 2-3 developers • Basic functionality -
Everything was fine until... • New PM with Big ambitions
• App redesign • New mobile features • New hires Suddenly, all the issues with the current app surfaced -
Looking under the hood • Fragment & View classes with
thousands of lines of code • No common pattern or structure • Manual JSON model parsing • No tests whatsoever • …. -
Twitch’s MVP pattern • Data Layer: ◦ Fetcher ◦ Models
◦ Api • Presentation Layer ◦ Presenter ◦ Tracker • View Layer ◦ ViewDelegate ◦ AdapterBinder Data Layer Presentation Layer View Layer Requests data Data loaded Callbacks Binds View User interaction Callbacks -
Unit tests as a culture • With a testable pattern
in place, no excuse for not testing your code! • Push for injecting dependencies • Run tests on every commit • Weekly report of % of code coverage -
Cleanup • Nullability annotations • Retrofit for all API calls,
get rid of Volley • GSON, remove all manual JSON parsing • Parceler for object serialization -
3 months later • App redesign complete • ~70% main
screens rewritten • ~15% code coverage • Big features added • Team of 11 developers -
Migrating to Kotlin • First Kotlin class introduced in June
2017 • Never looked back • Lessons learned: ◦ We quickly needed a standard for Kotling coding style ◦ Built-in nullability is a blessing, but beware of java interop • Code distribution as of September 2018: -
Introducing RxJava • Motivation ◦ Reduce callback hell of complex
use cases ◦ Cancel background tasks • Lessons learned ◦ Importance of educating the team on operators and general philosophy ◦ Enforce disposing of subscriptions, Kotlin extensions ◦ RxPlugins: Global error handler, JUnit rule for easy unit testing • Today: ◦ Most API calls return Observables ◦ Heavy usage of Subjects -
Dependency Injection with Dagger 2 • Motivation: ◦ Piping data
through deeply nested layers of objects is cumbersome ◦ No compile time validation, No object scoping ◦ Reduce usage of global singletons • Lessons learned: ◦ Even harder sell than RxJava: steep learning curve, no immediate benefit ◦ AndroidInjection helps reducing some initial boilerplate ◦ Benefits start showing only after a good portion of the code base is migrated • Today: ◦ ~90% of our Presenters are constructor injected ◦ Ongoing work to get rid of global Singletons -
Migrating to GraphQL • Motivation: ◦ Big company push to
move from REST to GQL ◦ Less dependencies on the backend, more flexibility ◦ Partial object caching • Lessons learned: ◦ Relying on a pre-alpha GQL library is scary ◦ Schema based, awkward versioning ◦ Beware of your fragments usage • Today: ◦ ~80% of our API calls go through GQL -
UI testing with Espresso • Motivation: ◦ Reduce workload on
QA for regression testing ◦ Reduce our release cadence to 2 weeks ◦ Improve confidence for big code changes • Lessons learned: ◦ Having a easy DSL and base framework helped a lot ◦ Team-wide “UI testing day” to improve coverage ◦ UI tests flakiness is a real pain • Today: ◦ ~70 unique tests, covers the main user flows ◦ Runs nightly, and on every alpha/beta push to google play -
Modularizing the app • Prepare for multiple apps & decentralized
teams • Improve build times • Prepare for App Bundles, Instant apps, downloadable features… -
Twitch MVP pattern 2.0 (?) • Current pattern still holding
strong 1+ year later • But can still be improved: ◦ Loosen coupling between Presentation and View layers ◦ Leverage ViewModel and LifecycleOwner from architecture components ◦ Automatic cleanup, easy way to persist Presenters Helium: Reactive MVP Framework. 100% Kotlin https://github.com/joaquim-verges/helium -
Latency / Performance monitoring • Framework to automatically get latency
metrics for every new screen • Daily/Weekly reports on latency changes • Frame rate monitoring tools and reports • Video performance monitoring tools and reports