it took for JDK 7 → 8 → 11) • Activity Embedding for Large Screen devices • Edge-to-edge layout (will be released soon!) • Compose Accessibility bug (released last week!) • Less FCM delay • Fixed a lot of platform bugs What we could do with top developers
architecture that make sense in mobile design ◦ It’s curated collection of best practices and recommendations for most common use cases • It's not something like Bible or silver bullet, meaning you need to be specific and creative to your own business / technical requirements. What "Google Guide" doesn't say (reprise)
Traditionally, View and Presenter calls methods in each other, which Jetpack Compose doesn't allow it Insightful Example - Circuit Ref: https://slackhq.github.io/circuit/
(Compose Nav + Jetpack Nav) navigation with KSP annotation ◦ Take a look with caution • Redwood by Cashapp (github.com/cashapp/redwood) • RIBs by Uber (github.com/uber/RIBs) • Good examples to see how devs can accept architectural principles into opinionated framework ◦ However, note that they’re designed to accelerate developer on their unique business requirements. Other Insightful Examples
◦ Why should I use DI in my project? ◦ Basic concepts of Dagger / Hilt ◦ How to use Dagger / Hilt ◦ Refer to d.android.com/training/dependency-injection What we don't discuss today
@Scope • DAG (Directed Acyclic Graphs) ◦ Binding, Component Dagger class A @Inject constructor(b: B) class B @Inject constructor(c: C, d: D) class C @Inject constructor() class D @Inject constructor() A B D C
KAPT) ◦ Same functionalities in Dagger + convenient extensions • Scope (!= Dagger Scope) ◦ Just a marker ◦ Aggregate using @MergeComponent, @ContributesTo Noteworthy alternative - Anvil (1)
discourages static top-level functions by building an object graph ◦ Compose - encourages top-level functions and parameter passing • State ◦ Dagger - encourages statefulness with objects and with scoping ◦ Compose - encourages making Composables stateless by state hoisting Downside of Dagger / Hilt (3)
by any descendant, not by a few of them.” • Not effective for nested structure • Hard to implement different life-cycle Why don’t we just use CompositionLocal?
class Composable as a state holder Activity / Fragment Stateless Composable State Holder Composable State Holder Composable Stateless Composable Stateless Composable Stateless Composable Stateless Composable Stateless Composable ...
Module B, it means that ... ◦ You failed to isolate Module A from Module B’s complexity ◦ APIs in Module B should defined well ◦ Or, Module B should be included in Module A • If not, you’re free to seperate them! Principle
is not large. ◦ The longer modularization is delayed, the more painful it becomes. ◦ Through modularization, previously undiscovered architectural problems can be found and solved, and a well-encapsulated structure can be maintained. ◦ Modularization creates a structure that is easier to test. When?
Both should depend on abstractions (e.g., interfaces). Dependency Inversion Principle (2) Data Interface Module Domain Module UseCase Data Module Repository Domain Module UseCase Data Impl Module Repository Impl Repository Interface
{ fun executeHoge() { repository.fuga() } } // in Data Interface Module interface FugaRepository { fun fuga() } // in Data Implementation Module internal class FugaRepositoryImpl : FugaRepository { override fun fuga() { ... } }