MVIDroid: рдирдИ MVI рд▓рд╛рдЗрдмреНрд░реЗрд░реА (рдореЙрдбрд▓-рд╡реНрдпреВ-рдЗрдВрдЯреЗрдВрдЯ) рдХреА рд╕рдореАрдХреНрд╖рд╛

рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░! рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдПрдХ рдирдИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬреЛ рдПрдорд╡реАрдЖрдИ рдбрд┐рдЬрд╝рд╛рдЗрди рдкреИрдЯрд░реНрди рдХреЛ рдПрдВрдбреНрд░реЙрдЗрдб рдкрд░ рд▓рд╛рддреА рд╣реИред рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ MVIDroid рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреЛрдЯрд▓рд┐рди рдореЗрдВ 100% рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд╣рд▓реНрдХрд╛ рдФрд░ RxJava 2.x рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдореИрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рд▓реЗрдЦрдХ рд╣реВрдВ, рдЗрд╕рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб GitHub рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ, рдФрд░ рдЖрдк рдЗрд╕реЗ JitPack (рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рд▓рд┐рдВрдХ) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рджреЛ рднрд╛рдЧ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╡рд░рдг рдФрд░ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдгред


MVI


рдФрд░ рдЗрд╕рд▓рд┐рдП, рдПрдХ рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ, рдореБрдЭреЗ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рдирд╛ рд╣реИ рдХрд┐ рдПрдорд╡реАрдЖрдИ рдХреНрдпрд╛ рд╣реИред рдореЙрдбрд▓ - рджреГрд╢реНрдп - рдЖрд╢рдп рдпрд╛, рдпрджрд┐ рд░реВрд╕реА рдореЗрдВ, рдореЙрдбрд▓ - рджреГрд╢реНрдп - рдЗрд░рд╛рджрд╛ред рдпрд╣ рдПрдХ рдРрд╕рд╛ рдбрд┐рдЬрд╝рд╛рдЗрди рдкреИрдЯрд░реНрди рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдореЙрдбрд▓ рдПрдХ рд╕рдХреНрд░рд┐рдп рдШрдЯрдХ рд╣реИ рдЬреЛ рдЗрдВрдЯреЗрдВрдЯреНрд╕ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд░рд╛рдЬреНрдп рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред рдкреНрд░рд╕реНрддреБрддрд┐ (рджреЗрдЦреЗрдВ) рдмрджрд▓реЗ рдореЗрдВ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЗ рдореЙрдбрд▓ (рджреЗрдЦреЗрдВ рдореЙрдбрд▓) рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реАрдВ рдЗрд░рд╛рджреЛрдВ рдХреЛ рдкреИрджрд╛ рдХрд░рддрд╛ рд╣реИред рдПрдХ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо рдлрд╝рдВрдХреНрд╢рди (рджреГрд╢реНрдп рдореЙрдбрд▓ рдореИрдкрд░) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░рд╛рдЬреНрдп рдХреЛ рдПрдХ рджреГрд╢реНрдп рдореЙрдбрд▓ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпреЛрдЬрдирд╛рдмрджреНрдз рд░реВрдк рд╕реЗ, рдПрдорд╡реАрдЖрдИ рдкреИрдЯрд░реНрди рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


MVI


MVIDroid рдореЗрдВ, рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╕реАрдзреЗ рдЗрд░рд╛рджреЛрдВ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдпрд╣ UI рдИрд╡реЗрдВрдЯ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рддрдм рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрдВрдЯреЗрдВрдЯ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рд░рд╛рдп


MVIDroid рдХреЗ рдореБрдЦреНрдп рдШрдЯрдХ


рдЖрджрд░реНрд╢


рдЖрдЗрдП рдореЙрдбрд▓ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ, рдореЙрдбрд▓ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдереЛрдбрд╝рд╛ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╣рд╛рдВ рдпрд╣ рди рдХреЗрд╡рд▓ рд░рд╛рдЬреНрдпреЛрдВ рдмрд▓реНрдХрд┐ рд▓реЗрдмрд▓реНрд╕ рдХрд╛ рднреА рдЙрддреНрдкрд╛рджрди рдХрд░рддрд╛ рд╣реИред рдореЙрдбрд▓ рдХреЛ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЗрдмрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреБрдЫ рдореЙрдбрд▓реНрд╕ рдХреЗ рд▓реЗрдмрд▓ рдХреЛ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдорд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдиреНрдп рдореЙрдбрд▓реЛрдВ рдХреЗ рдЗрд░рд╛рджреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдореЙрдбрд▓ рдХреЛ рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


рдЖрджрд░реНрд╢


MVIDroid рдореЗрдВ, рдореЙрдбрд▓ рдХреЛ MviStore рдЗрдВрдЯрд░рдлрд╝реЗрд╕ (рд╕реНрдЯреЛрд░ рдХрд╛ рдирд╛рдо Redux рд╕реЗ рдЙрдзрд╛рд░ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:


interface MviStore<State : Any, in Intent : Any, Label : Any> : (Intent) -> Unit, Disposable { @get:MainThread val state: State val states: Observable<State> val labels: Observable<Label> @MainThread override fun invoke(intent: Intent) @MainThread override fun dispose() @MainThread override fun isDisposed(): Boolean } 

рдФрд░ рддрд╛рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕:


  • рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рддреАрди рдЬреЗрдиреЗрд░рд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ: рд╕реНрдЯреЗрдЯ - рд╕реНрдЯреЗрдЯ рдХрд╛ рдкреНрд░рдХрд╛рд░, рдЗрдВрдЯреЗрдВрдЯ - рдЗрдВрдЯреЗрдВрдЯ рдХрд╛ рдкреНрд░рдХрд╛рд░ рдФрд░ рд▓реЗрдмрд▓ - рд▓реЗрдмрд▓ рдХрд╛ рдкреНрд░рдХрд╛рд░
  • рдЗрд╕рдореЗрдВ рддреАрди рдХреНрд╖реЗрддреНрд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: рд░рд╛рдЬреНрдп - рдореЙрдбрд▓ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐, рд░рд╛рдЬреНрдп - рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рд░рд╛рдЬреНрдп рдФрд░ рд▓реЗрдмрд▓ - рдЕрд╡рд▓реЛрдХрди рд▓реЗрдмрд▓ред рдЕрдВрддрд┐рдо рджреЛ рдлрд╝реАрд▓реНрдб рдХреНрд░рдорд╢рдГ рд╕реНрдерд┐рддрд┐ рдФрд░ рдЯреИрдЧ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рд╕рджрд╕реНрдпрддрд╛ рдХрд╛ рдЕрд╡рд╕рд░ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред
  • рдЙрдкрднреЛрдХреНрддрд╛ рдХрд╛ рдЗрд░рд╛рджрд╛
  • рдпрд╣ рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рд╣реИ, рдЬреЛ рдореЙрдбрд▓ рдХреЛ рдирд╖реНрдЯ рдХрд░рдирд╛ рдФрд░ рдЙрд╕рдореЗрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╕рднреА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рд░реЛрдХрдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИ

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╕рднреА рдореЙрдбрд▓ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдореБрдЦреНрдп рдзрд╛рдЧреЗ рдкрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдХрд┐рд╕реА рдЕрдиреНрдп рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рднреА рдпрд╣реА рд╕рдЪ рд╣реИред рдмреЗрд╢рдХ, рдЖрдк рдорд╛рдирдХ RxJava рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреГрд╖реНрдарднреВрдорд┐ рдХрд╛рд░реНрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдЕрдВрдЧ


MVIDroid рдореЗрдВ рдПрдХ рдШрдЯрдХ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд▓рдХреНрд╖реНрдп рджреНрд╡рд╛рд░рд╛ рдПрдХрдЬреБрдЯ рдореЙрдбрд▓ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдШрдЯрдХ рдореЗрдВ рд╕реНрдХреНрд░реАрди рдХреЗ рд▓рд┐рдП рд╕рднреА рдореЙрдбрд▓ рдХрд╛ рдЪрдпрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдХрдВрдкреЛрдиреЗрдВрдЯ рдЗрд╕рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдореЙрдбрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдореБрдЦреМрдЯрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг (рдореЙрдбрд▓, рдХрд╛рд░реНрдп рдФрд░ рдЙрдирдХреЗ рд╕рдВрдмрдВрдзреЛрдВ рдХреЛ рдмрджрд▓рдирд╛) рдХреЛ рдЫрд┐рдкрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЖрдЗрдП рдШрдЯрдХ рд░реЗрдЦрд╛рдЪрд┐рддреНрд░ рдХреЛ рджреЗрдЦреЗрдВ:


рдЕрдВрдЧ


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЖрд░реЗрдЦ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдШрдЯрдХ рдореЗрдВ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдмрджрд▓рдиреЗ рдФрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрд╛рд░реНрдп рд╣реИред


рдШрдЯрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рдПрдХ рдкреВрд░реА рд╕реВрдЪреА рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:


  • рдПрд╕реЛрд╕рд┐рдПрдЯреЗрдб рдЖрдиреЗ рд╡рд╛рд▓реЗ рд░рд┐рдкреНрд░реЗрдЬреЗрдВрдЯреЗрд╢рди рдЗрд╡реЗрдВрдЯреНрд╕ рдФрд░ рдЯреИрдЧ рдкреНрд░рддреНрдпреЗрдХ рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдорд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП
  • рдЖрдЙрдЯрдЧреЛрдЗрдВрдЧ рдореЙрдбрд▓ рд▓реЗрдмрд▓ рдХреЛ рдмрд╛рд╣рд░ рддрдХ рд▓рд╛рдПрдВ
  • рдЬрдм рдПрдХ рдШрдЯрдХ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рд╕рднреА рдореЙрдбрд▓ рдХреЛ рдирд╖реНрдЯ рдХрд░ рджреЗрддрд╛ рд╣реИ рдФрд░ рд╕рднреА рд╕рдВрдмрдВрдзреЛрдВ рдХреЛ рддреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ

рдШрдЯрдХ рдХрд╛ рдЕрдкрдирд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рднреА рд╣реИ:


 interface MviComponent<in UiEvent : Any, out States : Any> : (UiEvent) -> Unit, Disposable { @get:MainThread val states: States @MainThread override fun invoke(event: UiEvent) @MainThread override fun dispose() @MainThread override fun isDisposed(): Boolean } 

рдШрдЯрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:


  • рджреЛ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: UiEvent - рд╡реНрдпреВ рдЗрд╡реЗрдВрдЯреНрд╕ рдФрд░ рд╕реНрдЯреЗрдЯреНрд╕ рдХрд╛ рдкреНрд░рдХрд╛рд░ - рдореЙрдбрд▓ рдХреЗ рдкреНрд░рдХрд╛рд░
  • рдореЙрдбрд▓ рдХреНрд╖реЗрддреНрд░ рд╕рдореВрд╣ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдпрд╛ рдбреЗрдЯрд╛ рд╡рд░реНрдЧ рдХреЗ рд░реВрдк рдореЗрдВ) рдХреЛ рдПрдХреНрд╕реЗрд╕ рджреЗрдиреЗ рд╡рд╛рд▓реЗ рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╕рдорд╛рд╣рд┐рдд рдХрд░рддрд╛ рд╣реИ
  • рдЙрдкрднреЛрдХреНрддрд╛ рджреГрд╢реНрдп рдШрдЯрдирд╛рдПрдВ
  • рдпрд╣ рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рд╣реИ, рдЬреЛ рдШрдЯрдХ рдФрд░ рдЙрд╕рдХреЗ рд╕рднреА рдореЙрдбрд▓реЛрдВ рдХреЛ рдирд╖реНрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИ

рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ (рджреЗрдЦреЗрдВ)


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдбреЗрдЯрд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рджреГрд╢реНрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рджреГрд╢реНрдп рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рджреГрд╢реНрдп рдореЙрдбрд▓ рдореЗрдВ рд╡рд░реНрдЧреАрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЖрдорддреМрд░ рдкрд░ рдПрдХ рдбреЗрдЯрд╛ рд╡рд░реНрдЧ (рдХреЛрдЯрд▓рд┐рди) рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рджреЗрдЦреЗрдВ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:


 interface MviView<ViewModel : Any, UiEvent : Any> { val uiEvents: Observable<UiEvent> @MainThread fun subscribe(models: Observable<ViewModel>): Disposable } 

рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдереЛрдбрд╝рд╛ рд╕рд░рд▓ рд╣реИред рджреЛ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░: ViewModel - рд╡реНрдпреВ рдореЙрдбрд▓ рдХрд╛ рдкреНрд░рдХрд╛рд░ рдФрд░ UiEvent - рд╡реНрдпреВ рдЗрд╡реЗрдВрдЯреНрд╕ рдХрд╛ рдкреНрд░рдХрд╛рд░ред рдПрдХ uiEvents рдлрд╝реАрд▓реНрдб рдСрдмреНрдЬрд░реНрд╡реЗрдмрд▓ рд╡реНрдпреВ рдЗрд╡реЗрдВрдЯ рд╣реИ, рдЬреЛ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рдЗрди рд╕рдорд╛рди рдШрдЯрдирд╛рдУрдВ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИред рдФрд░ рдПрдХ рд╕рджрд╕реНрдпрддрд╛ () рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рд╡реНрдпреВ рдореЙрдбрд▓ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред


рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ


рдЕрдм рдЕрднреНрдпрд╛рд╕ рдореЗрдВ рдХреБрдЫ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдореИрдВ рдмрд╣реБрдд рд╕рд░рд▓ рдХреБрдЫ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВред рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдкреНрд░рдпрд╛рд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдм рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ рдФрд░ рдХрд┐рд╕ рджрд┐рд╢рд╛ рдореЗрдВ рдЖрдЧреЗ рдмрдврд╝рдирд╛ рд╣реИред рдЗрд╕реЗ UUID рдЬрдирд░реЗрдЯрд░ рд╣реЛрдиреЗ рджреЗрдВ: рдПрдХ рдмрдЯрди рдХреЗ рд╕реНрдкрд░реНрд╢ рдкрд░, рд╣рдо рдПрдХ UUID рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ рд╕реНрдХреНрд░реАрди рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВрдЧреЗред


рд╡рд┐рдЪрд╛рд░


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдореЙрдбрд▓ рджреЗрдЦреЗрдВ:


 data class ViewModel(val text: String) 

рдФрд░ рдШрдЯрдирд╛рдПрдБ рджреЗрдЦреЗрдВ:


 sealed class UiEvent { object OnGenerateClick: UiEvent() } 

рдЕрдм рд╣рдо рд╕реНрд╡рдпрдВ рджреГрд╢реНрдп рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ MviAbstractView рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


 class View(activity: Activity) : MviAbstractView<ViewModel, UiEvent>() { private val textView = activity.findViewById<TextView>(R.id.text) init { activity.findViewById<Button>(R.id.button).setOnClickListener { dispatch(UiEvent.OnGenerateClick) } } override fun subscribe(models: Observable<ViewModel>): Disposable = models.map(ViewModel::text).distinctUntilChanged().subscribe { textView.text = it } } 

рд╕рдм рдХреБрдЫ рдмреЗрд╣рдж рд╕рд░рд▓ рд╣реИ: рд╣рдо UUID рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЬрдм рд╣рдо рдПрдХ рдирдпрд╛ UUID рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ TextView рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЬрдм рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо OnGenerateClick рдШрдЯрдирд╛ рднреЗрдЬрддреЗ рд╣реИрдВред


рдЖрджрд░реНрд╢


рдореЙрдбрд▓ рдореЗрдВ рджреЛ рднрд╛рдЧ рд╣реЛрдВрдЧреЗ: рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиред


рдЗрдВрдЯрд░рдлреЗрд╕:


 interface UuidStore : MviStore<State, Intent, Nothing> { data class State(val uuid: String? = null) sealed class Intent { object Generate : Intent() } } 

рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ: рд╣рдорд╛рд░рд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ MviStore рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд░рд╛рдЬреНрдп (рд░рд╛рдЬреНрдп) рдФрд░ рдЖрд╢рдп (рдЗрд░рд╛рджреЗ) рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред рдЯреИрдЧ рдХрд╛ рдкреНрд░рдХрд╛рд░ - рдХреБрдЫ рднреА рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░рд╛ рдореЙрдбрд▓ рдЙрдиреНрд╣реЗрдВ рдЙрддреНрдкрдиреНрди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рд░рд╛рдЬреНрдп рдФрд░ рдЖрд╢рдп рд╡рд░реНрдЧ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВред


рдореЙрдбрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдореЙрдбрд▓ рдХреЗ рдЗрдирдкреБрдЯ рдкрд░, рдЗрдВрдЯреЗрдВрдЯреНрд╕ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рд╡рд┐рд╢реЗрд╖ рдЗрдВрдЯреЗрдВрдЯрдЯреНрдпреВрд╢рди рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреНрд░рд┐рдпрд╛рдУрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХрд╛рд░реНрдп рдирд┐рд╖реНрдкрд╛рджрдирдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдЗрдирдкреБрдЯ рд╣реИрдВ, рдЬреЛ рдЙрдиреНрд╣реЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдФрд░ рд▓реЗрдмрд▓ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рддрд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдо рдлрд┐рд░ Reducer рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдПрдХ рдирдП рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИред


рд╕рднреА рдЪрд╛рд░ рд░рдЪрдирд╛ рдореЙрдбрд▓:


  • IntentToAction - рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдЗрд░рд╛рджреЗ рдХреЛ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ
  • MviExecutor - рдХрд╛рд░реНрдп рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдФрд░ рдЯреИрдЧ рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИ
  • MviReducer - рдЬреЛрдбрд╝реЗ (рд░рд╛рдЬреНрдп, рдкрд░рд┐рдгрд╛рдо) рдХреЛ рдирдП рд░рд╛рдЬреНрдпреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ
  • MviBootstrapper рдПрдХ рд╡рд┐рд╢реЗрд╖ рдШрдЯрдХ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдореЙрдбрд▓ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╡рд╣реА рд╕рднреА рдПрдХреНрдЯреНрд╕ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдПрдХреНрдЬрд┐рдХреНрдпреВрдЯрд┐рд╡ рдХреЛ рднреА рдЬрд╛рддреЗ рд╣реИрдВред рдЖрдк рдПрдХ рдмрд╛рд░ рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЖрдк рдХрд┐рд╕реА рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХреБрдЫ рдШрдЯрдирд╛рдУрдВ рдкрд░ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЬрдм рдЖрдк рдПрдХ рдореЙрдбрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ рддреЛ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд░ рд╕реНрд╡рддрдГ рд╢реБрд░реВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдореЙрдбрд▓ рдХреЛ рд╕реНрд╡рдпрдВ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдореЙрдбрд▓ рдХреЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ MviStoreFactory рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдФрд░ MviDefaultStoreFactory рдХреЗ рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдХрд╛рд░рдЦрд╛рдирд╛ рдореЙрдбрд▓ рдХреЗ рдШрдЯрдХреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдореЙрдбрд▓ рдЬрд╛рд░реА рдХрд░рддрд╛ рд╣реИред


рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдХрд╛ рдХрд╛рд░рдЦрд╛рдирд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рджрд┐рдЦреЗрдЧрд╛:


 class UuidStoreFactory(private val factory: MviStoreFactory) { fun create(factory: MviStoreFactory): UuidStore = object : UuidStore, MviStore<State, Intent, Nothing> by factory.create( initialState = State(), bootstrapper = Bootstrapper, intentToAction = { when (it) { Intent.Generate -> Action.Generate } }, executor = Executor(), reducer = Reducer ) { } private sealed class Action { object Generate : Action() } private sealed class Result { class Uuid(val uuid: String) : Result() } private object Bootstrapper : MviBootstrapper<Action> { override fun bootstrap(dispatch: (Action) -> Unit): Disposable? { dispatch(Action.Generate) return null } } private class Executor : MviExecutor<State, Action, Result, Nothing>() { override fun invoke(action: Action): Disposable? { dispatch(Result.Uuid(UUID.randomUUID().toString())) return null } } private object Reducer : MviReducer<State, Result> { override fun State.reduce(result: Result): State = when (result) { is Result.Uuid -> copy(uuid = result.uuid) } } } 

рдпрд╣ рдЙрджрд╛рд╣рд░рдг рдореЙрдбрд▓ рдХреЗ рд╕рднреА рдЪрд╛рд░ рдШрдЯрдХреЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдлреИрдХреНрдЯреНрд░реА рд╡рд┐рдзрд┐ рддреИрдпрд╛рд░ рдХрд░рддреА рд╣реИ, рдлрд┐рд░ рдареЗрдХреЗрджрд╛рд░ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж, рд░рд┐рдбреНрдпреВрд╕рд░ рдФрд░ рдЙрд╕рдХреЗ рдЕрдВрдд рдореЗрдВ рд░рд┐рдбреНрдпреВрд╕рд░ред


рдЕрдВрдЧ


рдШрдЯрдХ рд░рд╛рдЬреНрдп (рд░рд╛рдЬреНрдп рд╕рдореВрд╣) рдбреЗрдЯрд╛-рд╡рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рд╣реИрдВ:


 data class States(val uuidStates: Observable<UuidStore.State>) 

рдПрдХ рдШрдЯрдХ рдореЗрдВ рдирдП рдореЙрдбрд▓ рдЬреЛрдбрд╝рддреЗ рд╕рдордп, рдЙрдирдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдореВрд╣ рдореЗрдВ рднреА рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред


рдФрд░, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЦреБрдж:


 class Component(uuidStore: UuidStore) : MviAbstractComponent<UiEvent, States>( stores = listOf( MviStoreBundle( store = uuidStore, uiEventTransformer = UuidStoreUiEventTransformer ) ) ) { override val states: States = States(uuidStore.states) private object UuidStoreUiEventTransformer : (UiEvent) -> UuidStore.Intent? { override fun invoke(event: UiEvent): UuidStore.Intent? = when (event) { UiEvent.OnGenerateClick -> UuidStore.Intent.Generate } } } 

рд╣рдореЗрдВ MviAbstractComponent рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛, рд░рд╛рдЬреНрдпреЛрдВ рдФрд░ рджреГрд╢реНрдп рдШрдЯрдирд╛рдУрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реБрдП, рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдХреЛ рд╕реБрдкрд░ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдЙрддреНрддреАрд░реНрдг рдХрд┐рдпрд╛, рдФрд░ рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рд╣рдордиреЗ рдПрдХ рдкрд░рд┐рд╡рд░реНрддрди рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдпрд╛ рдЬреЛ рд╡реНрдпреВ рдЗрд╡реЗрдВрдЯреНрд╕ рдХреЛ рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдХреЗ рдЗрд░рд╛рджреЛрдВ рдореЗрдВ рдмрджрд▓ рджреЗрдЧрд╛ред


рдореИрдкрд┐рдВрдЧ рдореЙрдбрд▓ рджреЗрдЦреЗрдВ


рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╢рд░реНрддреЗрдВ рдФрд░ рдкреНрд░рд╕реНрддреБрддрд┐ рдореЙрдбрд▓ рд╣реИрдВ, рдпрд╣ рдПрдХ рдХреЛ рджреВрд╕рд░реЗ рдореЗрдВ рдмрджрд▓рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо MviViewModelMapper рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:


 object ViewModelMapper : MviViewModelMapper<States, ViewModel> { override fun map(states: States): Observable<ViewModel> = states.uuidStates.map { ViewModel(text = it.uuid ?: "None") } } 

рд╕рдВрдЪрд╛рд░ (рдмрд╛рдЗрдВрдбрд┐рдВрдЧ)


рдЕрдХреЗрд▓реЗ рдШрдЯрдХ рдФрд░ рдкреНрд░рд╕реНрддреБрддрд┐ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдиреНрд╣реЗрдВ рдЬреБрдбрд╝рд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдЧрддрд┐рд╡рд┐рдзрд┐ рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ:


 class UuidActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_uuid) bind( Component(UuidStoreFactory(MviDefaultStoreFactory).create()), View(this) using ViewModelMapper ) } } 

рд╣рдордиреЗ рдмрд╛рдЗрдВрдб () рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рдЬреЛ рдЙрдирдХреЗ рдореЙрдбрд▓ рдХреЗ рдореИрдкрд░реНрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдШрдЯрдХ рдФрд░ рджреГрд╢реНрдпреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рд▓реЗрддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ LifecycleOwner (рдЬреЛ рдЧрддрд┐рд╡рд┐рдзрд┐ рдФрд░ рдЯреБрдХрдбрд╝рд╛ рд╣реИ) рдкрд░ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐ рд╣реИ рдФрд░ Arch рдкреИрдХреЗрдЬ рд╕реЗ DefaultLifecycleObserver рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛ 8 рд╕реНрд░реЛрдд рд╕рдВрдЧрддрддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрджрд┐ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдЖрдк рдЬрд╛рд╡рд╛ 8 рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рджреВрд╕рд░рд╛ рдмрд╛рдБрдз () рд╡рд┐рдзрд┐ рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИ, рдЬреЛ рдХрд┐ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИ рдФрд░ MviLifecyleObserver рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдкрдХреЛ рдЬреАрд╡рди рдЪрдХреНрд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╕реНрд╡рдпрдВ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред


рд╕рдВрджрд░реНрдн


рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб, рд╕рд╛рде рд╣реА рд╕рд╛рде рдЬреЛрдбрд╝рдиреЗ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╕реНрддреГрдд рдирд┐рд░реНрджреЗрд╢ GitHub рдкрд░ рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/hi417763/


All Articles