Share
Embed
Android Architecture 총정리
당신의 아키텍처, 뭔가 잘못된 것 같은 느낌에 시달리고 있지는 않나요? MVP부터 MVVM, Flux 그리고 클린 아키텍처까지 Best Practice를 중심으로 현업에서 어떤 아키텍처를 적용할 것인가에 대해, 그리고 아키텍처 관점에서 의존성 주입, Rx, 코루틴, 멀티모듈 등의 기술을 어떻게 적용할 수 있을지, 2018년에 이어 더욱 깊은 내용으로 다뤄봅니다.
동영상 링크: https://www.youtube.com/watch?v=0LL7FCWTxoo
Sa-ryong Kang
April 05, 2019
Transcript
60 slides
-
Who is this guy? • ҃۱ 19֙ର SW ূפয •
ತস ޙо: Ҵীࢲ ೠ ߣ, ೠҴীࢲ ف ߣ झఋস ହস ҃ • IBM iX Japanীࢲ Android/iOS Senior Specialist۽ Ӕޖ • Droid Knights 2018 - ղо উ٘۽٘ ূפযо غਸ ٸ ইޖب ঌ۰ ঋ Ѫٜ -
IBM iX Japan - We’re building business by design •
Design Thinking, Mobile Interaction, Digital Strategy, … • ઝр ࢜܂Ҋ ߀Ҋ, ਬ ೱੋ न ӝࣿ/ࢎসਸ ҳഅ೧ח ஶࢸ ઑ • ਃ Ҋё: ੌࠄ 10 Ӓܛ, ೯ࢎ, ন ೦ҕࢎ -
ݾର • Part I. ࢲۿ 1. ࢎ೦ 2. ࢶࣻ ध:
উ٘۽٘ ইఃఫ 4࠙݅ী ߶ۅӝ - MVC, Clean Architecture, Testability, Reusability • Part II. Non-MVC ইఃఫ ୨ܻ 1. Non-MVC ইఃఫ ӝࠄ ࢸ҅ ۚ 2. MVP 3. MVVM 4. Redux • Part III. New Trend in 2019 1. Rx vs non-Rx 2. Multi-module • Part IV. Best Practices -
1. दೞӝ ࢎ೦ • ա ӝ Ә - 45࠙
ъী ցޖ ݆ Ѧ ӝೞदݶ ݒ Ҍۆ.. • ঐӝ Ә - ਗܻܳ ೧ೞח Ѫ ؊ ਃ • ޖడҊ ժٙೞӝ Ә - ৵ ۠ ফӝܳ ೞחоܳ ೧ೞҊ, ౸ױ ৈ۞࠙ झ झ۽ • ࢎ ୫ ޖॶݽ: ठۄ٘ח ইې ݂ীࢲ ߉ਵप ࣻ णפ • https://speakerdeck.com/saryong -
৵, ౠ߹ উ٘۽٘ ইఃఫ ࢸ҅/ҳഅী যࢲ, ࠺౸ ࢎҊ о ਃೠо?
• General Practiceח ؘ݆ Best Practiceח ইࠁӝ য۵ • बয Gࢎо ݅ٚ ࢠઑର цۿਸ߅ ৈо.. • ইఃఫ ಁఢ Ѯਸ ݍࠁѱ ೧ח Ӗ ݆݅ ೨ब ୍ী ೧ ফӝೞ ח Ӗ ݒ ൞߅ೞ • э ܴਸ о ইఃఫ ಁఢب п ࢚ടী ٮۄ ݒ ਵ۽ ҳഅؼ ࣻ -
2. ࢶࣻध • Architecture ӝࠄ ӝࠄ: MVCۆ ޖੋо? •
Model = State + ࠺ૉפझ ۽ + ؘఠ ࣗ • View = UI (ࠁా declarativeೞѱ ҳഅؽ) • Controller = Flow ۽ + [࠺ૉפझ ۽] + [State] -
(30ୡ݅ী ೧ೞח) Clean Architecture ӝࠄ • MVCীࢲ Modelਸ ࠙೧ →
Domain Layer + Data Layer • MVCীࢲ ࠺ૉפझ ۽ਸ ࠙೧ → Presentational Logic (in Presenter) / Domain Logic (in UseCase) : https://qiita.com/koutalou/items/07a4f9cf51a2d13e4cdc -
• Ӓؘ۠, ই ࠗ࠙ۢ ࠁח Presentation Logicী ۽ ݾೞח
ਬח? • بݫੋ ۽ ରೞח ࠗ࠙ (࢚ਵ۽) - ࠗ࠙ জ ҃, о ࠂ ೠ ࠺ૉפझ ۽ ߔূ٘ ࢲߡী ઓೣ • ࠂೞҊ (ࠗ࠙) ࠺زӝੋ ࢚క ҙܻ, ӒܻҊ ۄ ࢎ োز ഻ঁ ࠂ ೞҊ ਃೠ ޙઁ • ߄Լ ফӝೞݶ ݽ߄ੌ ইఃఫীࢲ о դઁח tight coupling between ui and state changes ܳ যڌѱ ೧ࣗೡ Ѫੋо ޙઁ -
ইఃఫ ҙীࢲ ইې ف ѐ֛ ৵ Ӓܻ ਃೠо? • పझ
оמࢿ • ࢎਊࢿ • “դ ਬపझ ٮਦ ਃ হয!”ۄҊ ର݃ ݈ೞӝ ী.. • Testablilityо ڄযח ٘ۆ ޖੋо ࢤп೧ ࠇद → Tightly-coupled • పझ оמࢿ ڄযח ٘ח ਃ ۄ࠳۞ܻ ߸҃, ӝ߈ ҳઑ ߸҃ী ೞӝо য۵ • “അपਵ۽ ೠ ߣ ૠ ٘ܳ ېझ/Fragment ױਤ۽ ࢎਊ оמೠ ҃о ݃ա ظ?”ۄҊ ର݃ ݈ೞӝ ী.. • Re-usabilityۆ ѱ গୡী ޖա ࢤп೧ࠇद → ೠ ݽٕച, ङച • ࢎਊࢿ ڄযח ҳઑח ӝמ ߸҃ / ഛࢿ ڄয ≒ ٘ оةࢿ ڄয -
एযоח ց.. ۡ ٸ উ٘۽٘ ѐߊੋ ѱ ࠗՍۣ যו զ,
ҳ ইٜ ز֎ CTOܳ ݅աҊ ৡ ࢎש աܳ ࣑ࠗܰ. -
֎... Activityח ݻ ө ࠌա? Dilbert © 2018, Andrews McMeel
Syndication ֎?! -
Ҋࣻۄݶ ࠁా ݻ ୌ ب ח ࠌ؍ؘ.. .. WTF?! ޤঠ
Ӓ بب ޅ ೧ࠄ Ѣয? Dilbert © 2018, Andrews McMeel Syndication -
Fat Activity/Fragment - ݅ঈ Ӕਗ ৈӝࢲ ֙ ࠂण: ৵ Android
MVCח աࢂо? • Activityо ೡ ࣻ ח ੌ • ۄࢎ ҙܻ, ݽٚ UI ۽ - ۨইਓ ࢤࢿ, ۪؊݂, গפݫ࣌, Shared Preferences, ੌ IO, ചݶ ജ, ӂೠ ࢸ, Loader, Ӓ ৻ী ࣻ ߔ о • ӝࠄ Android Architectureীࢲ Activityۆ? • Controller + View + alpha + omega = god • Fragmentب Ӓր नੌࡺ.. -
Non-MVC ࢸ҅ ۚ • Non-MVCীࢲ Activityח ޖੋо? → Activityח ஶ܀۞!
(ӒѪب ই ઁೠੋ..) • MVP (Ҿӓ) Ӕߨ • Activityীࢲ View৬ Controller ೡਸ ୭ೠ ࡐই View৬ Presenter۽ ֈӣ. Activityח ࣽࣻ flow ҙܻ ೡ ਤ • MVVM/Redux ١ Ӕߨ • ݃ଲо۽ Activityח ୭ೠ ੌࠗ context ઓ ӝמ݅ ೞب۾.. View logic ୭ೠ data bindingਵ۽ ҳഅ • ৈӝࢲ ޙ: ৵ ҳӖ (ߓӝب য۵Ҋ Rxо হਵݶ ઁ۽ ҳഅب উ غח) ViewModel݅ਸ AAC(Android Architecture Component)ীࢲ ਗೞחо? • ӝઓ Activity/Fragment ഋకܳ ӵڰܻ ঋਵݶࢲ ࢎਊࢿ/ࢤࢿ ֫ ইఃఫܳ ҳഅ оמೞӝ ٸޙ* ※: য٣өա ୶ஏੑפ. -
Model-View-Presenter? • 1990֙ ୡ IBMীࢲ ୭ୡ۽ ҳഅ • 2006֙ Martin
Fowler ࣗѐ۽ օܻ ঌ۰ ଵઑ: GUI Architectures https://martinfowler.com/eaaDev/uiArchs.html • ࢎप উ٘۽٘ ୡӝࠗఠ ҳਵ۽ ೧ઉ ৳؍ ইఃఫ • Ӕؘ ೠޛ р ҳઑ ইצо? ইب ॳաਃ? • , ইب ݆ ॺפ. ܳ ٜݶ, э ഥࢎоਃ. -
Presenter View Model ࢎਊ ੑ۱ਸ ాࠁ ؘఠ јन ਃ ؘఠ
߸҃ ాࠁ ࠭ ߸҃ ਃ • ݽٚ Presentational Business Logicਸ Presenterীࢲ ܻ • Viewח Presenter ਃী ٮۄ ࣻزਵ۽ UIܳ ܻೣ -
Google Architecture Blueprint۽ ࠙ࢳ೧ࠁח MVP ೨ब • https://github.com/googlesamples/android-architecture/tree/todo- mvp/ •
Contractor Pattern • View, Presenterח interface ഋక۽ ࢲ۽ܳ ଵઑ • V৬ P ҳഅ ࢴѢա, Pо ۖಬ ઓੋ APIܳ Ӕೡ ৈܳ ਗୌ ࠉࣧ -
/** * This specifies the contract between the view and
the presenter. */ public interface TasksContract { interface View extends BaseView<Presenter> { // ... void setLoadingIndicator(boolean active); void showTasks(List<Task> tasks); void showAddTask(); void showTaskDetailsUi(String taskId); } interface Presenter extends BasePresenter { // ... void loadTasks(boolean forceUpdate); void addNewTask(); void openTaskDetails(@NonNull Task requestedTask); void completeTask(@NonNull Task completedTask); void activateTask(@NonNull Task activeTask); void clearCompletedTasks(); void setFiltering(TasksFilterType requestType); TasksFilterType getFiltering(); } } • TODO জ п স(task)ܳ ࠁৈҊ ୶о ೞח ചݶਸ ਤೠ TasksContractor interface • View-Presenter р োѾਸ Ր • Good?! -
• द ೠ ߣ ࣁ ࠇद. • যۄ? Presenter ݫٜࣗ٘ਸ
ࠁפ ؘ ఠܳ ֈѹח Ѫٜ ֎? • Ӓۢ ࢚క ࠁܳ Viewо ыחח ফ ӝ?! /** * This specifies the contract between the view and the presenter. */ public interface TasksContract { interface View extends BaseView<Presenter> { // ... void setLoadingIndicator(boolean active); void showTasks(List<Task> tasks); void showAddTask(); void showTaskDetailsUi(String taskId); } interface Presenter extends BasePresenter { // ... void loadTasks(boolean forceUpdate); void addNewTask(); void openTaskDetails(@NonNull Task requestedTask); void completeTask(@NonNull Task completedTask); void activateTask(@NonNull Task activeTask); void clearCompletedTasks(); void setFiltering(TasksFilterType requestType); TasksFilterType getFiltering(); } } -
/** * Display a grid of {@link Task}s. User can
choose to view all, active or completed tasks. */ public class TasksFragment extends Fragment implements TasksContract.View { private TasksContract.Presenter mPresenter; //... TaskItemListener mItemListener = new TaskItemListener() { @Override public void onTaskClick(Task clickedTask) { mPresenter.openTaskDetails(clickedTask); } @Override public void onCompleteTaskClick(Task completedTask) { mPresenter.completeTask(completedTask); } @Override public void onActivateTaskClick(Task activatedTask) { mPresenter.activateTask(activatedTask); } }; //... private static class TasksAdapter extends BaseAdapter { private List<Task> mTasks; private TaskItemListener mItemListener; public TasksAdapter(List<Task> tasks, TaskItemListener itemListener) { setList(tasks); mItemListener = itemListener; } } } • Bingo! - п ࢚కী ٮܲ కझܳ viewо ౸ױ೧ࢲ ࠁղҊ • Ӓ item listenerܳ ഐೞח ࠗ࠙ਸ Ѣ ठ۞ ৢۄщ؊פ.. • Task ё ࢚కܳ Viewо ыҊ Ҋ, যڃ presenter ೣࣻо ഐغযঠ ೡ ܳ View Ѿೠ?! -
• ?! Ѥ MVPо ইפਗ਼ই! • Viewо passiveೞ ঋ! •
গୡী Activityо Controller, Fragment о View ೡਸ ೞب۾ ݅ٚ Ѫ о, ੌ ӏݽ ࢚ জীࢲח ޙઁо ؼ ࣻ ח ࢸ҅ -
• ۠ য়೧ ٸޙী Martin Fowlerח Presenterۄח ܴਸ ತӝೞҊ Supervising
ControllerۄҊ ࠗܳ Ѫਸ ઁউ. (ӒܻҊ Viewח Passive View ۽ ܴࠗ) • Ref: Retirement note for Model View Presenter Pattern https://martinfowler.com/eaaDev/ModelViewPresenter.html . -
؊ ࣁೠ Ѥ… ৵ Viewח Passive ೧ঠೞחо, ӒܻҊ ߄ۈೠ View৬
Presenter ೡ ޖੋо? ࣘदਗೞѱ ঌ۰٘݀פ… (ই݃ب) -
• ఋ ইఃఫীب ਊغח ফӝ݅ ೞݶ, • Android ҃, nested
ҳઑ۽ т ࣻ߆ী হ. • Ӓۢ ҳӖ ৵ ইఃఫ ࢎਸ ۧѱ ૧ਸ ө? • : ౠ ഥࢎ ҕध ࢠ যڃ بܳ оҊ ٜ݅য ࣻب ח ਸ ܻ ف ী ل ਃо P V M Home MVP* P V M Banner MVP P V M Original List MVP P V M Preview List MVP ※: য٣өա ୶ஏੑפ. -
MVVM • MVVMীࢲ Viewח ־ҳੋо? • XML! DataBinding! • XMLী
view logicਸ ನೣ → Declarativeೠ UI ۽ ҳഅ оמ → BindingAdapter ઑ, RxJava/ RxBinding بਵ۽ View ࢚ࣻ ҳഅਸ Activity/Fragment۽ࠗఠ ࡐ ই ৢ ࣻ http://kyubid.com/blog/understanding-mvvm-on-android-tutorial-05-introduction-to-reactive-programming-with-rxjava/ -
• ViewModel • Ӓ ۽ ة݀ੋ दझమ • Viewী Ӕೡ
ࣻب হҊ, ઓ ب ݽܴ • AAC ViewModel • LifeCycle ਗ ӝמ ৻ী ౠ߹ೠ ӝמ হ (ରӝ ߡীࢲب SavedStateо ୶оغח ب) • Life Cycle ܻܳ ҳഅೞҊ AAC-ViewModelਸ ࢎਊೞ ঋইب ޖߑ • Pro tip: MVVM ҳઑ ࢸݺীࢲ AAC Ӓܿࠗఠ աয়ח Ӗۄݶ Ҋ Ѣܰदݶ ؾפ -
Redux - ߊ • Part I.ীࢲ ফӝ೮٠, ݽ߄ੌ জীࢲ о
դઁ ೞաח ࠂೠ ࢚క ٜਸ যڌѱ ӭՔೞҊ ਬࠁࣻࢿ ֫ѱ ҳഅೡ Ѫੋо ޙઁ • ߊ࢚ਸ ߄Լࢲ জ ߮ܳ State Machineਵ۽ ܻೠݶ যڄө? • Life Cycle ܻ۽ Ҏݠܻ এਸ ੌ әѺ যٝ • ࢚కী ٮۄ ܰѱ زೞח UIܳ ࠁ ҙਵ۽ ҙܻ оמ • ౠചݶীࢲ ࣻ ػ ղਊ (: “જইਃ” ࢚క ߸҃) ܲ Ҕীࢲ ۽ ਊ -
• Ӓؘ۠.. • State Machineਸ ҳഅೞ ࠁݶ.. п ۽
୶࢚ചܳ যڌѱ ೡ ݆ Ҋ ਸ ೞѱ ؽ • ࢚క: ݢ ࢚కܳ ೞח ࠗ࠙ ࠁా enum class ইפݶ, sealed class۽ ҳഅ • ࢚క ୌ(transition/flow): যڃ ઑѤীࢲח B۽, ژ ܲ ઑѤীࢲח C۽ ߸҃ • ۽ ࣻ೯: п ࢚కо ߸҃ غਸ ٸ ࣻ೯೧ঠೡ पઁ ۽ • ਤ ࣁ ਃࣗ ࠂبী ٮۄ ࢚ടী ݏѱ ҳഅ೧ঠೞ݅ о ߧਊੋ ߑߨ ೞա ח uni-directionalೠ pipeline ഋక -> ߄۽ Flux ҳઑ! -
MVI? Flux? Redux? • Flux: Facebookীࢲ, ਢ ۿূ٘ ࢚క ܻܳ
ҙҊ ӭՔೞѱ ೞӝ ਤ ೧ Ҋউೠ Architectural Pattern. ױߑೱ pipelined loopܳ ా೧ ߮ܳ ܻ • MVI: Fluxী View ܻ ١ ݽ߄ੌ ҙ۲ ղਊਸ ୶о೧ࢲ ࠗܰח ܴ. উ٘۽٘ ѐߊীࢶ Flux৬ э ਊযۄҊ ࢤп೧ب ޖߑ • Redux: Flux ಁఢ ߸ഋ ҳഅ о ബਯۄҊ ঌ۰ ҳഅ. (ޛۿ Java Script۽..) - immutable state, single source of truthܳ पഅೠ ױࣽೠ ҳഅ • Dan Abramovۄח ѐߊо Ҋউ. 100ৈ ী ࠛҗೠ ۄ࠳۞ܻ۽ ݽٚ Flux ҳഅܳ ಣ -> flux ਗ Ҋউীѱ ੋ ߉ റ, ߄۽ Facebookীࢲ झ ਓ -
• Action: ࢚కܳ ߸҃ೞۄח ݺ۸݅ਸ о • ࠁా Action Creatorܳ
ా೧ ٜ݅য • State: ࢚క ؘఠ݅ਸ о. no logic • immutable (fluxח mutable) • Store • ࢚క ࣗ • ࢚కܳ ߸҃दఃҊ, ా ೞח ೡ • RxJava Coroutineਵ۽ ࣚऔѱ ҳഅ оמ • Reducer • ࣽࣻ ೣࣻ(pure function) ഋక۽ ࢚క ߸҃ਸ ҳ അ: (State, Action) -> new State Ӓܿ : https://speakerdeck.com/yuyakaido/droidkaigi-2019 -
Ӓۢ side effect ܻח ־о? → Middleware! Ӓܿ :
https://speakerdeck.com/yuyakaido/droidkaigi-2019 -
Redux ױ • • ࢚క ܻীࢲ ۄ ࢎ ೱਸ
যו ب ߓઁೡ ࣻ • ചݶীࢲ back ߡౡ ־ܲ റী ٍןѱ ߊࢤೠ API ী۞.. э গݒೞҊ դ೧ೠ ࢚ടب ബҗਵ۽ оמ • ࢚క ࠗ࠙, ࠗ࠙, ܻ ࠗ࠙ ৮߷ աׇઉ ӝ ٸޙী ࣻ/ഛ ӓب۽ ಞೣ • Functionalೠ ҳઑ ౠࢿ࢚ ਬ పझܳ ࢿೞח Ѫ ӓب۽ ಞܻೣ • Debugging नࣁ҅! അ ݽٚ ࢚కܳ ഛੋೡ ࣻ Ҋ, ࢚క ߸ࣻ чਸ ࣻ೧ࢲ ࢚కܳ ߄Լࠅ ࣻب • ױ • ࢚ೠ ࣻળ ण ࠺ਊ ࣗਃ • ٘ ૐо, ౠ boiler plate ٘ ߈ࠂ ࢤ ೖೞӝ য۰ -
Flux / Redux അ৬ ې • അ • ReKotlin, RxRedux
ਵա അ۽ࢶ ҳഅਸ ୶ୌ • State / Action ਸ View۽ ೡ ࣻب ݅ ViewModel۽ب оמ • ӒܻҊ Flux ҃ח Storeܳ ViewModel۽ ҳഅ! • RxJava۽ Store, ӒܻҊ side effectܳ ܻೞח middlewareܳ ҳഅ vs Coroutine + LiveData ઑ • ې? • Rxܳ Ҷ ॳ ঋইب غח use caseо ࠗ࠙Ҋ, coroutine ജ҃ ࢿࣼ/উച ؽী ٮۄ әѺ coroutineਵ۽ ब ֈযт ٠ • അ ܨੋ Redux-Thunk middlewareܳ Redux-Sagaо ೡ Ѫਵ۽ ࢚ • Coroutineҗ ৮߷ೞѱ ݒ غח async loop ҳઑ • ӓب۽ ইܴҊ ӭՔೠ పझ ٘ ࢿ оמ -
1. Multi-module! • ৈӝࢲ ਫ਼द ޙ • internal class (inner
class ইש) ޖੋ ইदաਃ? • private / protected / internal / public internal - public ରח? • internal ध߹ -> ܲ module (packageо ইש) ীࢲ ࠁ ঋѱ ೣ • android gradle plugin 3.0.0ࠗఠ compile -> implementationਵ۽ ߄Ո ਬ о ޖੋ ইदաਃ? • ݣ౭ ݽٕ ਗ ӝמ ъച غݶࢲ ୶оػ ѐ֛ • ഛח, compile == api ۽ ߄Պ -
ଵઑ оמ • Compile (== api) ध߹ • ౠ߹ ೞ
ঋইب ࣚ ݽٕө ଵઑ оמ • ߄Լ ফӝೞݶ, module2о ߸҃ غ ݶ app ݽٕب ஹ ੌ ೧ঠೣ Ӓܿ : https://speakerdeck.com/sansanbuildersbox/multi-module-android-application -
ଵઑ ࠛо • implementation ध߹ • ݺदਵ۽ ೞ ঋ
ࣚ ݽٕ ଵઑ ࠛо • ߄Լ ফӝೞݶ, module2о ߸҃ غ যب app ݽٕ ஹ ੌೡ ਃо হ Ӓܿ : https://speakerdeck.com/sansanbuildersbox/multi-module-android-application -
• ݣ౭ ݽٕ ৵ ॳחо? • അपੋ ਬ: ࠽٘ ࣘب
• ಽ ࠽٘: 36.4s → 30s, incremental build: 14.2s → 7s • Ref: https://speakerdeck.com/sansanbuildersbox/multi-module-android- application • ৵? ػ ਬח annotation processing. kapt ҃ח ইب incremental processingਸ ਗೞ ঋ. • Ӓ৻ realmҗ э byte code weavingਸ ೞח ۄ࠳۞ܻܳ ߹ب ݽٕ۽ ࡐח Ѫ ݅ਵ۽ 30% ࠽٘ ࢿמ ೱ࢚ • ബਯੋ ࠙স ۽ࣁझ оמ: ݽٕ ߹۽ ҳഅ Ѻܻ / పझо оמ • ة݀ੋ ࢸ҅ܳ ୢ -
• ݽٕ যڌѱ ա־חо? - (1) Layer ߹ ࣻ ܻ࠙
• Presentation / Domain / Data Layer • ױ, Applicationীࢲ DBܳ ࢤࢿ೧ঠ ೞӝ ٸޙী, P -> D -> L ഋక ߓח ࠛоמ • app DIܳ , ui / data ݽٕী domain ݽٕ ੑؼ ࣻ ب۾ ೣ Ӓܿ : https://speakerdeck.com/sansanbuildersbox/multi-module-android-application -
• ݽٕ যڌѱ ա־חо? - (2) ࣻಣ ܻ࠙ • ചݶ߹
/ ӝמ߹۽ ܻ࠙ → feature߹ ة݀ࢿ ഛࠁ • ઓࢿ ӝળ ܻ࠙: Realm ١ black magic ҅ ӝࣿ ࢎਊػ ࠗ࠙ ӓ۱ ߹ب ݽٕ۽ ܻ࠙ • Eg. SanSan Eight App ҃, realm object ߹ب ݽٕ ܻ࠙݅ਵ۽ ಽ ࠽٘ दр 6m 46s → 4m 27s • : ࢚ഐ ଵઑ • উ٘۽٘ ݽٕ ଵઑח ױߑೱ݅ ೲਊೞ۽ নߑೱ ଵઑо ࠛо • ف ѐ ചݶ п ࢲ۽ܳ दೡ ࣻ ח ҃ח, п intentܳ оઉঠ ೞ۽ ܻ࠙о ࠛоמ೧ • Intent ࢤࢿ ੋఠಕझ݅ਸ ыҊ ҳഅ ୭࢚ਤ ݽٕ(:app) ࣗਬ → DI۽ যয়ӝ • ঔध navigation ېझܳ ٜ݅Ҋ п ݽٕ ੋఠಕझ݅ ыب۾ ҳഅ (DroidKaigi 2018 জ ଵઑ) • Tip: Daggerܳ ਊೠ ੑ + ࢎਊ ۄఠо زदী ਃೠ ҃ۄݶ, AssistedInjection ਸ ࢎਊ -
• Dependency Inversion: ઁө Androidীࢲ ਃद ػ হ؍ ࢸ҅
ਗ • ࢚ਤ ݽٕ ೞਤ ݽٕী ઓࢿ যࢲח উ ػ & ࢚ਤ ݽٕ ೞਤ ݽٕ ݽف ੋఠಕझী݅ ઓೠ • A ёо B ё ۨಌ۠झܳ ଵઑೞח न, interfaceܳ ଵઑೞৈ ҳഅ ઓࢿਸ Ր • Bо ߸҃غযب Aח ஹੌೡ ਃо হ • زੌೠ ੋఠಕझܳ ы݅ ഃ ܲ ۽ਵ۽ ҳഅػ ઁ3 ݽٕ۽ औѱ ߸҃ оמ → Dependency Injection بਸ ߉ਵݶ п ݽٕ ߹ ࢸਸ ੌҙػ ߑधਵ۽ ࣚऔѱ ࣻ оמ -
2. RxJava vs Coroutine vs LiveData • ৵ ਃೠо? •
Reactive: ࠺زӝੋ ܻܳ imperativeೞѱ ܻೡ ࣻ ѱ ೧ષ • RxJava • ৈ, Androidীࢲ ࠺زӝ ܻ ਤೠ അઓೞח о ъ۱ೞҊ ಞܻೠ ࣻױ • Androidীࢲ ࠂೠ ࢚కܻܳ ҙਵ۽ ҳഅ оמ • View - ViewModelҗ оҮܳ ਤೠ black magic झ۞ নೠ ҳഅب оמ • eg. ࢚ടী ٮۄ ࣽରਵ۽ प೯೧ঠ ೞח গפݫٜ࣌ਸ пп Completable۽ ೠ റ, Combine೧ࢲ प೯ -
• ۠ Ѫب оמ! • ViewGroup ߄Չ ٸ݃ ViewModel
ాܳ ߉ਸ ࣻ ب۾ View ஏীࢲ ഐೡ ࣻ ח ಌ ೣࣻ internal fun createVerticalCenterPublisher(layout: View): Observable<Int> = Observable.create<Int> { emitter -> emitter.onNext(layout.bottom - layout.top) val callback = View.OnLayoutChangeListener { _, _, top, _, bottom, _, _, _, _ -> emitter.onNext(bottom - top) } layout.addOnLayoutChangeListener(callback) emitter.setCancellable { layout.removeOnLayoutChangeListener(callback) } }.subscribeOn(AndroidSchedulers.mainThread()) .throttleLatest(100, TimeUnit.MILLISECONDS, true) .map { it / 2 } -
Coroutine • ޤо જо? • ࢿמ : coroutine is light-weight
threads • Rxࠁ ؏ য۵ • ࠁ functionalೠ ҳഅ - Saga ಁఢ э ഋక ҳഅী ఌਘ • ઁח উӝী যٜ - Kotlin 1.3җ ೣԋ ध ߡ غҊ, ୭न ࢎনী ݏ নೠ ਗ غয . • lifecycle-viewModel-ktx 2.1.0 (അ alpha03)ࠗఠ lifecycle-awareೠ Coroutine Scope ੋ viewmodelScopeܳ ҕध ਗ • retrofit ରӝ ߡীࢲ “suspend fun”ਸ ഋక۽ api interface оמ (അ “Deferred”ܳ ܻఢೞח ഋక) -
LiveData • LiveDataী ೧ ֤ೞӝ ী.. • View - ViewModel
(or Presenter) р ߮ ాী যࢲ о ࢚ੋ ߮ ా ׳ח যڃ ౠਸ оઉঠೡө? • ߮ ׳ UI झۨ٘ীࢲ ܞઉঠ ೠ • Side Effect ҕਬо оמ೧ঠೠ. -> ए ݈۽ ೞݶ ೞա ߮ܳ ৈ۞ ߮ ೩ٜ۞о ҕਬೡ ࣻ যঠ ೠ • ী۞ܳ skip ೡ ࣻ যঠ ೠ • → RxSwift ҃, Signal/Driverо ী ೧ -
• LiveData ౠ • ӝࠄਵ۽ UI threadীࢲ ز • Side
Effect(ч ߸ച, ߮) ҕਬо оמ • Configuration ߸҃ द ݄݃ ߊࢤೠ ߮ܳ replay ೧ષ (ױ, ب ঋ ߡӒо ࢤӡ ৈ ) • transformationਸ ా೧ RxJava combineҗ ࠺तೞѱ ҳഅ оמ • → RxSwift Driver৬ ਬࢎೠ ѐ֛ + LifeCycle-awareness • LiveDataח ઁ ॳחо? • Rx о ইצ ࠁ৮ • DataBinding ਊب۽ח ୶ୌೞ ঋ -
ࢶ ઑѤ • জ ӏݽ: Toy projectо ইפҊ पઁ Play
Storeী ৢۄৡ জੋо • ࢸ҅: Clean Architecture ١ ੜ ਊغয חо • పझ: Unit Testо ਃࣗਃࣗ ੜ ҳഅغয חо • ٘ ಿ: ղ ۽ંীب ы ॶ݅ೠ അ ݆о -
Google IO 2018 • https://github.com/google/iosched • Clean Architecture - Domain
layer UseCase ҳഅ ߂ పझ • LiveData ࢎਊ ࣻ: RxJava ইפݶ উ ؼ Ѫ э ӝמٜөب ކٶ MediatorLiveData۽ ҳഅ! • ೡ : LiveDataܳ पઁ۽ ۧѱ ॳח Ѫ ӓ۱ ࠺୶ୌ • ӝఋ ইఃఫ ৻ਵ۽ ࣁࠗ ٘ ҳഅী ଵҊೡ ݒ ݆ -
DroidKaigi 2018 • https://github.com/DroidKaigi/conference-app-2018 • о ݽߧੋ MVVM ҳઑ •
о ഴܯೞҊ ӭՔೠ Dagger • Domain ۽ Data ۨয Repository ಁఢਵ۽ ҳഅ • NavigationController - ݒ ഴܯೠ coordination উ • gradle kts -
DroidKaigi 2019 • https://github.com/DroidKaigi/conference-app-2019 • ݣ౭ ݽٕ ҳഅ • +
iOSب ਗ • Flux ҳઑ • Dagger ഛ • AssistInjection! • ୭न UI ҳഅ! - Custom LayoutManager જ ܳ ࠅ ࣻ ! -
I’ll be back! • DroidKnights 2020 উ٘۽٘ ইఃఫ ࣁߣ૩ दܻૉ۽
جই২פ. ղਊ ই݃ب.. • Coroutine + Arrow۽ ҳഅೠ functionalೠ Redux ҳઑ बக ࠙ࢳ • ӏݽ Multi-module ۽ં ҳ୷ • Dagger ࢎਊಁఢ ୨ܻ • (ѐോস ؍) ࠶۽Ӓ ѐפ! - 4/20ࠗఠ • पઁ ۽ંীࢲ ח Test-Driven Development • Dagger 2 Dependency Injection ҳഅ ۚ ୨ܻ ъࢎܕ Email: [email protected] Blog: https://medium.com/@justfaceit Slide: https://speakerdeck.com/saryong