Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[EN] High-Performance Android: Rebirth of our US App

mercari
September 30, 2017
120

[EN] High-Performance Android: Rebirth of our US App

mercari

September 30, 2017
Tweet

More Decks by mercari

Transcript

  1. Summary • Redesigned the US Mercari app in June of

    this year • Huge UI/architecture changes • All changes were made in order to improve the overall product • Mercari Android team used our trademark “high-performance” teamwork!
  2. You know what needs to be done. Every Section 9

    member has a unique ability. And you work best on your own. But individual success is a reflection of strong teamwork. We’re just like Public Security Section 9 “ ” Daisuke Aramaki, 2002 (Ghost in the Shell: Stand Alone Complex)
  3. Working with “speed” in mind 1. Code that anyone can

    replicate 2. Minimize all problems to optimal size 3. Actively integrate new technologies
  4. • Layer that houses the data • Has an interface

    that does not need to worry about storage location 1. Code that anyone can replicate View View Model Service Repository • Activity/Fragment/View • Only layer that touches Context • Slave to ViewModel (no logic) • Houses logic not directly related to display • Network access, storage access, etc. • All logic is stateless, and the Service layer does not hold a state • Houses the display logic • Pure Java, is JUnit testable
  5. Connect all layers via RxJava2 stream → Use RxJava2 together

    as a team 1. Code that anyone can replicate
  6. Making our weapon (RxJava2) high-context Recalculate the shipping cost when

    the method, payer, or weight changes Flowable.combineLatest ( shippingClass, shippingPayer, (c, p) -> { .... } Process input as fields are filled out .filter (signal -> !itemName.get().isEmpty() && itemCategory.has() && itemCondition.has()) .flatMapMaybe(signal -> ... Preventing overuse (backpressure) RxTextView .textChangeEvents(hashTag) .throttleLast ( 100, TimeUnit.MILLISECONDS )....
  7. 1. Code that anyone can replicate Same blueprint Same weapons

    MVVM + Flux oriented layered architecture RxJava2 ...etc
  8. 2. Minimize all problems to optimal size • Trying to

    tackle big problems all at once is too much • We want to split big problems into small pieces • Shoving everything into Activity when creating the screen • Shoving multiple API requests and processing into one class • ...etc Break it down and make it configurable with DI !!
  9. Any issues that aren’t directly related should be solved outside

    You know DI, right? class SellService { private SellApi sellApi; private ItemApi itemApi; private AddressApi addressApi; private SuggestApi suggestApi; SellService(ItemApi itemApi, SellApi sellApi, AddressApi addressApi, SuggestApi suggestApi) { this.sellApi = sellApi; this.itemApi = itemApi; this.addressApi = addressApi; this.suggestApi = suggestApi; }
  10. You know DI, right? Instead, focus on what you should

    be solving yourself! /** * Get user's default deliver address. */ @CheckReturnValue Maybe<DeliverAddress> getDefaultAddress() { return addressApi.getDeliverList() .filter(resp -> !resp.addresses.isEmpty()) .map(resp -> { Optional<DeliverXX> address = Stream.of(resp.addresses) .filter(addr -> Defaults.get(addr.isDefault)) .findFirst(); if (address.isPresent()) { return address.get(); } else { // if couldn't found default, use first one return resp.addresses.get(0); } }); }
  11. 2. Minimize all problems to optimal size • Smaller than

    View/ViewModel/Service/Repository • Try to use constructor injection when possible Wait, but Activity and Fragment don’t have constructors... Dagger 2 !!
  12. Implement injection into the classes that can’t touch constructors Activity

    injection public class ItemDetailActivity extends BaseActivity { @Inject ItemDetailViewModel viewModel; @Inject UrlConstruct urlConstruct; @Inject MasterData masterData; ... @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_item_detail); AppComponent.Holder.get(this) .plus(new ItemDetailComponent.Module(this, itemId)) .inject(this);
  13. 2. Minimize all problems to optimal size • If the

    problem is simple, the road to the goal is shorter • High-quality communication within the team • Unit tests become easier to write, and the fastest way to test code • (side-effect) Making use of Dagger2’s scope,               we were also able to deal with the Activity lifecycle  
  14. Kotlify progress Every other week - Discuss how Kotlin is

    going in Tokyo and San Francisco - Share technical information - but still we’re looking for a strong reason, why Kotlin? Kotlin used for all new files since Google I/O announced support
  15. Working with “speed” in mind 1. Code that anyone can

    replicate 2. Minimize all problems to optimal size 3. Actively integrate new technologies
  16. Challenges we face with transpacific development Strategizing before writing code

    High-quality PRs Branchify large requirements Early mornings Screen hero (Rough) daily reports Travel Same blueprint Same weapons “To be a high-performance development team, we must…as;ldkfjasdlfkjasd” (←all talk) “High-Performance” Really high-performance “This should work, right? Let’s go for it!!” (←action!)
  17. Highly Scalable Android Team in the near future… 100 Android

    Engineers More than 100 times performance
  18. Summary • We redesigned the whole US Mercari app in

    June • We’re going to capture the US market with the new architecture focused on a high-speed, high-performance team • Then we’ll go even higher, creating a scalable team whose performance just keeps increasing with size, and taking over the “global marketplace” • We’re so high-performance, like a racecarrrrr