※Notes記事では、英語のセッション動画やポッドキャストの内容を(雑に)英語でメモに書き残すことを行っています。本記事は、あくまで動画を見ながら、参考程度に読んでいただくことを想定しています。Notes記事には雑メモ程度のものだったり、書き起こしのようなものもあります。これから実際の動画を見る際には、本記事の内容が少しでもお役に立てば幸いです。(内容において不備、誤字脱字等ありましたら気軽にご連絡いただけると嬉しいです。)
本記事は、droidcon NYC 2017 - App Development - Pragmatic Best Practices - YouTubeの記事です。
このセッションの内容は、事前アンケートの回答をもとに、Androidアプリケーションの設計について重きをいたセッションでした。YigitさんとIsraelさんのお勧めの設計や開発の仕方などを幅広く(かつところどころジョークも交えて)説明されています。
Since the talk is about very broad topic, they decided to take survey and they got 150 answers!
Survey
Q: Most difficult part of building an app?
- 1st - Architecture
- 2nd - Android specifics
Q: What is a recurring problem in your codebase?
- 1st. Testing, Code bloat
- 2nd. Architecture
Q: What design patterns that you want to replace in your codebase?
60% of them: - God classes - God activities - MVP - MVC - Mwhatever - Lack of architecture - Singletons
etc.
Talking about architecture, but why Now?
Architecture was always there, but just popular now because..
Ecosystem gets mature now:
- networking code => retrofit
- image loading => glide, picasso
- view fragments => fragments, conductor
- APK needs to be small => split APKs etc
As Android platform becomes better, people's expectations and apps become bigger as well:
- 60fps
- lots of functionality, complex features
- lots of integrations
- works fully offline
- (Gmail example) HTML everywhere, rich text editor
- ART >>>> Dalvik
Yigit's architecture recommendations
Separation of Concerns
Before building architecture, have separation of concerns first.
- Have it in day one, stick to it
- Make sure things deal with one thing
- Build architecture over time, as needed
- Be careful to write application in modularized way so that you can flex it to better suit your needs in the future.
Do Not Over-Engineer
- Libraries, guides are tools, not goals
- The goal is to ship and maintain
- Don't use something just because X does
- The problem is not yours , neither their solution
Israel's architecture recommendation
MVWW => Model View Whatever Works
Dependency Injection
- Allows to declare dependencies of an object upfront
Single Responsibility
- Similar to "separation of concerns"
- A class has only one reason to exist
- Have layered architecture
- View layer: View manipulation
- Logic layer: Screen behavior
- Data layer: Network, DB, Memory cache, Repository Interface
- In Complex screens,
- Multiple logic layer components each with a single responsibility.
- Logic layer components can subscribe to events tied to their logic ( Rx, EventBus)
Shared Logic
- E.g. Like a tweet
-> Have "Use Cases" to decouple logic and make it possible to reuse it within the app
"You don't do this in day One; trying to solve a problem before it exists is a bad idea"
Goal
- Each layer has a reason to exist
- Consistency in codebase
- Testable logic layer
- Reusable of logic layer
Android Specifics
Lifecycles
- Embrace lifecycles, you cannot ignore
- It is a solved problem, if you follow guides(but too many solutions you can apply out there)
- If you have a proper separation lifecycle issue can be very tiny.
4 Options
- Manual Lifecycle Handling
Not recommended
- Data Binding
Data Binding already knows how not to leak your Activity or observers, so you do not to need to think about lifecycle at all for normal cases
- Live Data
If you are comfortable using RxJava already then maybe no need
- AutoDispose
If you use RxJava you may want to use this
.autoDisposeWith(this).subscribe(adapter:setList)
Configuration changes
- Config Change != App Restrat
Config Change
- Decouple UI and data
- You may be able to use ViewModel
- Views restore their states automatically
- If UI is data drive, no extra work necessary
App Restart
- Derive UI from disk
- Use savedInstanceState
- e.g. getIntent… setArguments .. etc.
- Nothing in memory survives :(
- NBU was one of the top problems in the survey
Saved State
- View's information(e.g. RecyclerView position)
- UI's arguments
Disk
- Application data
Fragmentation - how to deal with it
Hardware
- Generate a class that defines hardware profile - low, medium, high depending on RAM and CPU cores and frequency
- year-class lib foundation to classify hardware profiles https://github.com/facebook/device-year-class
- Based on the hardware profile apply animations e.g. rich, medium or none animations
Dependencies
RxJava
- "With great power comes great responsibility"
- You need to be careful what kind of operators you are using; you need to understand what you are using otherwise you break your application
Dagger 2
- You need to build dependency graph
- many annotations to remember
Warnings
- Rx and Dagger help to scale your app
- It comes at a cost. Learning their DSL, idioms.
- The team needs to learn it and grow criteria for code reviews.
- Moreover, many new hires will need to learn Android and these new idioms all at once.
Testing
If you want to refactor you need to have test.
- Testing is a must!
- If there are tests, make sure they pass
- If there are no tests, at first, write them
- Unit test logic layer (at least)
Best answers
Q: What is a recurring problem in your codebase?
- Keyboard
Q: Patterns you dislike and will like to replace in your code base?
- Hungarian notation
Q: What is the best part of your codebase?
- None
以上です!