ææ°ã®ã¢ããªã±ãŒã·ã§ã³ã®ã»ãšãã©ã®ã³ãŒãã¯ãããããAndroid 4.0ã®æä»£ã«æžãæ»ãããŸããã ã¢ããªã±ãŒã·ã§ã³ã¯ãContentProviderã RoboSpice ã ããŸããŸãªã©ã€ãã©ãª ãããã³ã¢ãŒããã¯ãã£ã®ã¢ãããŒãã®æä»£ãçãå»¶ã³ãŸããã ãããã£ãŠãæ©èœã®å€æŽã ãã§ãªããæ°ãããã¬ã³ãããã¯ãããžãŒãããŒã«ã«ãæè»ã«å¯Ÿå¿ã§ããã¢ãŒããã¯ãã£ãæã€ããšãéåžžã«éèŠã§ãã
ãã®èšäºã§ã¯ãIFunnyã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ãŒãç§ãã¡ãé å®ããŠããååãããã³éçºããã»ã¹äžã«çºçããäž»ãªåé¡ã®è§£æ±ºæ¹æ³ã«ã€ããŠã話ããããšæããŸãã
éçºã®åºæ¬ãšèãããã€ã³ãããå§ããŸãããã
- ããŒã å
ã§åãèšèªã話ãã æ°ããéçºè
ã¯ããããç¬èªã®ã¢ãŒããã¯ãã£ã®ããžã§ã³ãæã¡ãæ¢åã®ã³ãŒãã«ãšã³ããããŒãå°å
¥ã§ããŸãã åå¥ã®ç¬ç«ããã¢ããªã±ãŒã·ã§ã³ã³ã³ããŒãã³ããæ§ç¯ããããã®åºæ¬çãªãã¿ãŒã³ãå¿
èŠã§ãã
- ã°ããŒãã«ãªæœè±¡åã®æ¬ åŠã åæã«ãã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£ã®æç€ºã§ã¯ãªãããã¬ãŒã ã¯ãŒã¯ã«èªåèªèº«ãæŒã蟌ã¿ãåã³ã³ããŒãã³ãããã䟿å©ãªæ¹æ³ã§å®è£
ããããããŸããã ã¢ãŒããã¯ãã£ã¯éçºè
ã®ããã«æ©èœããå¿
èŠãããããã®éã¯ã§ããŸããã
- ã³ã³ããŒãã³ãã®åå©çšïŒæ¢åã®ã³ãŒããã§ããã ãç°¡åã«äœ¿çšããæ©èœã
- ç»é¢å転åŠçã ã¢ããªã±ãŒã·ã§ã³ã®äž»ãªåé¡ã®1ã€ã¯ãã¢ã¯ãã£ããã£/ãã©ã°ã¡ã³ãã®å転ãŸãã¯åäœæåŸã®ç»é¢ã®å埩ã§ãã ãããŸã§ããã³ãã«å
ã®ãã¹ãŠã®ããŒã¿ãonSaveInstansState / onRestoreInstanceStateã«è¿œå ããŸãã ã
- ã¢ããªã±ãŒã·ã§ã³ã©ã€ããµã€ã¯ã«ã®æ£ããåŠç ã
- åæ¹åããŒã¿ãããŒïŒã¢ããªã±ãŒã·ã§ã³å
ã§ã®ããŒã¿åŠçã®é åºã®èšŒæ ã
ããã§ã¯ãç§ãã¡ãäœã«å°éããååé¡ãã©ã®ããã«è§£æ±ºãããã«ã€ããŠé çªã«è©±ããŸãããã

æåã¯ãã¢ããªã±ãŒã·ã§ã³ã®éçºæã«ãã¢ã¯ãã£ããã£/ãã©ã°ã¡ã³ããã³ã³ãããŒã©ãŒãšããŠæ©èœããMVCããããŸããã å°èŠæš¡ãªã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããã¯åŒ·åãªæœè±¡åãå¿
èŠãšããªãéåžžã«äŸ¿å©ãªãã¿ãŒã³ã§ããããã®ãã¿ãŒã³ã¯å
ã
ãã©ãããã©ãŒã ã«ãã£ãŠæ±ºå®ãããŠããŸããã
ããããæéã®çµéãšãšãã«ãã¢ã¯ãã£ããã£/ãã©ã°ã¡ã³ãã¯å€èªäžèœãªãµã€ãºã«æé·ããŸãïŒç§ãã¡ã®èšé²ã¯ããã©ã°ã¡ã³ãã®1ã€ã«ãã3000è¡ã®ã³ãŒãã§ãïŒã æ°ããæ©èœã¯ãããããçŸåšã®ã³ãŒãã®ç¶æ
ã«äœããã®åœ¢ã§åºã¥ããŠããããããã®ã¯ã©ã¹ã«ã³ãŒãã远å ãç¶ããããšã¯å°é£ã§ãã
ç»é¢å
šäœãç¬ç«ããã³ã³ããŒãã³ãã«åå²ããå¿
èŠããããšããçµè«ã«éãããã®ããã«å¥ã®ãšã³ãã£ãã£ãç¹å®ããŸããã
ViewController.javapublic abstract class ViewController<T extends ViewModel, D> { public abstract void attach(ViewModelContainer<T> container, @Nullable D data); public abstract void detach(); }
ViewModelContainer.java public interface ViewModelContainer<T extends ViewModel> extends LifecycleOwner { View getView(); T getViewModel(); }
ãã©ã°ã¡ã³ãã¯æ¬¡ã®ããã«ãªããŸãã
ChatFragment.java public class ChatFragment extends TrackedFragmentSubscriber implements ViewModelContainer<ChatViewModel>, IMessengerFragment { @Inject ChatMessagesViewController mChatViewController; @Inject TimeInfoViewController mTimeInfoViewController; @Inject ChatToolbarViewController mChatToolbarViewController; @Inject SendMessageViewController mSendMessageViewController; @Inject MessagesPaginationController mMessagesPaginationController; @Inject ViewModelProvider.Factory mViewModelFactory; @Inject UnreadMessagesViewController mUnreadMessagesViewController; @Inject UploadFileProgressViewController mUploadFileProgressViewController; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.face_to_face_chat, container, false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mChatViewController.attach(this); mSendMessageViewController.attach(this); mChatToolbarViewController.attach(this); mMessagesPaginationController.attach(this); mUnreadMessagesViewController.attach(this); mTimeInfoViewController.attach(this); mUploadFileProgressViewController.attach(this); } @Override public void onDestroyView() { mUploadFileProgressViewController.detach(); mTimeInfoViewController.detach(); mUnreadMessagesViewController.detach(); mMessagesPaginationController.detach(); mChatToolbarViewController.detach(); mSendMessageViewController.detach(); mChatViewController.detach(); super.onDestroyView(); } @Override public ChatViewModel getViewModel() { return ViewModelProviders .of(this, mViewModelFactory) .get(ChatViewModel.class); } }
ãã®ã¢ãããŒãã«ã¯ãå€ãã®å©ç¹ãåæã«ãããŸãã
- ã³ã³ããŒãã³ãã®åå©çšã
ããšãã°ãæ€çŽ¢ããŒã䜿çšããããã€ãã®ç»é¢ããããŸãã



ãã®åäœã远å ããã«ã¯ãã³ãŒãã«ç»é²ããã ãã§ãã
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mSearchFieldViewController.attach(this); }
ãŸãã¯ãããšãã°ãè€æ°éžæã®å¯èœæ§ãããæ€çŽ¢çµæã§ãããããŒã¿åèªäœããã®ããŒã¿ã®ãœãŒã¹ãããã²ãŒã·ã§ã³ãšæŠç¥ããã£ãã·ã¥ã¯å®å
šã«ç°ãªããŸãã ãã£ã¹ãã¬ã€ã®ã¿ãäžèŽããŸãïŒ


- ãã¹ãå®¹ææ§ã åäžã®ç»é¢ã®åäœããã¹ãããããã«ãã©ã°ã¡ã³ã/ã¢ã¯ãã£ããã£ãäœæããå¿
èŠã¯ãããŸããã
- ã¢ãžã¥ãŒã«æ§ã ã¢ããªã±ãŒã·ã§ã³ã®åã
ã®éšåïŒUIãŸãã¯ããŒã¿åŠçïŒã¯ãçžäºã«åç
§ããããšãªãéçºã§ããŸãã
- ãããåæã«ãéçºè
ã«å¶éã¯è¿œå ããããåã
ã®ã³ã³ããŒãã³ãããšã«ç¬èªã®ã¢ãŒããã¯ãã£ã¢ãããŒãïŒMVCãMVIãMVVMããŸãã¯ãã®ä»ã®MVXïŒã䜿çšã§ããŸãã ãã®æœè±¡åã¯ãAndroidã®ã³ã³ããŒãã³ãããç§ãã¡ãåé¢ããã³ãŒããèšè¿°ããããã®äžè¬çãªã¹ã¿ã€ã«ãèšå®ããã ãã§ãã
次ã«ãããŒã¿æ§é ãæŽçããå¿
èŠããããŸãã ç»é¢ã®ç¶æ
ãã©ããã«ä¿åããã¢ã¯ãã£ããã£/ãã©ã°ã¡ã³ãã®åçŸãäœéšããå¿
èŠããããŸãã
ãã³ãã«å
ã®ããŒã¿ã¹ãã¬ãŒãžãç§ãã¡ã«åããªãçç±ïŒ
- å®åã³ãŒããå€ãããã
- ãã©ã°ã¡ã³ããšã¡ãœããåŒã³åºãã¡ãœããã®ã©ã€ããµã€ã¯ã«ã¯ããªãè€éã§ãã ãã¥ãŒã¹ããŒããšããŒã¿ãä¿åããããšã¯æããã§ã¯ãããŸããã
å€ãã®ãã¥ã¢ã³ã¹ã®1ã€ãããã£ãŠãã¢ã¯ãã£ããã£ã¯ãã¥ãŒã®ç¶æ
ã埩å
ããŸãã
protected void onRestoreInstanceState(Bundle savedInstanceState) { if (mWindow != null) { Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG); if (windowState != null) { mWindow.restoreHierarchyState(windowState); } } }
ãŸãã RecycleViewã¢ããã¿ãŒããªãŒããŒã©ã€ããããonRestoreInstanceStateå
ã§æŽæ°ãããå Žåã埩å
ãããããã©ã«ãã®ã¹ã¯ããŒã«ã¯ãªã»ãããããŸãã
- ãã¹ãŠã®éãããŒã¿ã«ã€ããŠã¯ãããŒã¿ããŒã¹å
ã®ã¹ãã¬ãŒãžãæŽçããå¿
èŠããããŸããããããªããšãTooLargeTransactionExceptionããã£ããã§ããŸãã
retain fragmentã䜿çšããããšã«ããŸãããã€ãŸããViewModelã®åœ¢åŒã§Googleããã®äŸ¿å©ãªã©ãããŒã§ãã ãããã®ãªããžã§ã¯ãã¯ãåå©çšã§ããªããã©ã°ã¡ã³ããšããŠFragmentManagerã«ååšããŸãã
ä»çµã¿
FragmentManagerã¯ããã®ãããªãªããžã§ã¯ããFragmentManagerNonConfigã®å¥ã®ãã£ãŒã«ãã«ä¿åããŸãã ãã®ãªããžã§ã¯ãã¯ãFragmentManagerã®å€åŽã®ã¡ã¢ãªé åïŒActivityClientRecordãšåŒã°ãããªããžã§ã¯ãïŒã§ActivityãšFragmentManagerãåäœæããŠãåç¶ããŸãã ãã®ãªããžã§ã¯ãã¯Activity.onDestroyã§åœ¢æãããç¶æ
ãActivity.attachã«åŸ©å
ããŸãã ãããã圌ã¯ç»é¢ãå転ãããšãã«ã®ã¿å埩ããããšãã§ããŸãã ã€ãŸã ã·ã¹ãã ãã¢ã¯ãã£ããã£ããéä»ããããå Žåãäœãä¿åãããŸãã ã
åViewControllerã«ã¯ãç¶æ
ãé
眮ãããç¬èªã®ViewModelãå¿
èŠã§ãã ãŸããããŒã¿ã衚瀺ãããã¥ãŒãå¿
èŠã§ãã ãã®ããŒã¿ã¯ãã¢ã¯ãã£ããã£ãŸãã¯ãã©ã°ã¡ã³ãã«ãã£ãŠå®è£
ãããViewModelContainerãä»ããŠæž¡ãããŸãã
次ã«ãã³ã³ããŒãã³ãéã®ããŒã¿ãšç¶æ
ã®ãããŒãæŽçããå¿
èŠããããŸãã å®éããã®ã¿ã¹ã¯ã«ã¯ããã€ãã®ãªãã·ã§ã³ã䜿çšã§ããŸãã ããšãã°ãViewControllerãšViewModelã®éã®ããåãã«Rxã䜿çšããã®ãè¯ã解決çã§ãã
ãããã®ç®çã§LiveDataã䜿çšããããšã«ããŸããã
LiveDataã¯Rxã®äžçš®ã®ã¹ããªãŒã ã§ãããå€ãã®ãªãã¬ãŒã¿ãŒã¯ããŸããïŒå®éã«ã¯ãªãã¬ãŒã¿ãŒãååã§ã¯ãªããããLiveDataãšRxã䞊ã¹ãŠäœ¿çšããå¿
èŠããããŸãïŒããããŒã¿ããã£ãã·ã¥ããã¢ããªã±ãŒã·ã§ã³ã®ã©ã€ããµã€ã¯ã«ãåŠçã§ããŸãã
äžè¬ã«ããã¹ãŠã®ããŒã¿ã¯ViewModelå
ã«ãããŸãã ãã®å ŽåãããŒã¿åŠçã¯ãã®å€éšã§è¡ãããŸãã ViewControllerã¯åã«ã€ãã³ããããªã¬ãŒããViewModelã®ãªãã¶ãŒããŒãä»ããŠããŒã¿ãåŸ
æ©ããŸãã
ViewModelå
ã«ã¯ãããããã¹ãŠã®ç¶æ
ããã£ãã·ã¥ããå¿
èŠãªLiveDataãªããžã§ã¯ãããããŸãã ç»é¢ãå転ãããšãViewControllerãåäœæãããããŒã¿ããµãã¹ã¯ã©ã€ãããæåŸã®ç¶æ
ãããã«ãªããŸãã
ChatViewModel.java public class ChatViewModel extends ViewModel { private final MessageRepositoryFacade mMessageRepositoryFacade; private final CurrentChannelProvider mCurrentChannelProvider; private final SendbirdConnectionManager mSendbirdConnectionManager; private final MediatorLiveData<List<MessageModel>> mMessages = new MediatorLiveData<>(); private final MutableLiveData<String> mMessage = new MutableLiveData<>(); @Inject public ChatViewModel(MessageRepositoryFacade messageRepositoryFacade, SendbirdConnectionManager sendbirdConnectionManager, CurrentChannelProvider currentChannelProvider) { mMessageRepositoryFacade = messageRepositoryFacade; mCurrentChannelProvider = currentChannelProvider; mSendbirdConnectionManager = sendbirdConnectionManager; initLiveData(); } public LiveData<List<MessageModel>> getMessages() { return mMessages; } public void writeMessage(String message) { mMessage.postValue(message); } public void sendMessage() {
ãã¥ãŒãåæåããã«ã¯ãButterKnifeãšViewHolderã¢ãããŒãã䜿çšããŠãåæåããããã¥ãŒã®åŒ±ç¹ãåãé€ããŸãã
åViewControllerã«ã¯ç¬èªã®ViewHolderããããViewHolderã®ãã¿ãããç¡å¹åããããšã attachã®åŒã³åºãã«åæåãããŸãã 衚瀺å
ã®ãã¹ãŠã®ãã£ãŒã«ãã¯ãåŸç¶ã®ãã®ã«ç»é²ãããŸãã
ViewHolder.java public class ViewHolder { private final Unbinder mUnbinder; private final View mView; public ViewHolder(View view) { mView = view; mUnbinder = ButterKnife.bind(this, view); } public void unbind() { mUnbinder.unbind(); } public View getView() { return mView; } }
次ã«ãç»é¢ã®ã³ã³ãããŒã©ãŒã«ã€ããŠèª¬æããŸãã
SendMessageViewController.java @ActivityScope public class SendMessageViewController extends SimpleViewController<ChatViewModel> { @Nullable private ViewHolder mViewHolder; @Nullable private ChatViewModel mChatViewModel; @Inject public SendMessageViewController() {} @Override public void attach(ViewModelContainer<ChatViewModel> container) { mViewHolder = new ViewHolder(container.getView()); mChatViewModel = container.getViewModel(); mViewHolder.mSendMessageButton.setOnClickListener(v -> mChatViewModel.sendMessage()); mViewHolder.mChatTextEdit.addTextChangedListener(new SimpleTextWatcher() { @Override public void afterTextChanged(Editable s) { mChatViewModel.setMessage(s.toString()); } }); } @Override public void detach() { ViewHolderUtil.unbind(mViewHolder); mChatViewModel = null; mViewHolder = null; } public class ChatViewHolder extends ViewHolder { @BindView(R.id.message_edit_text) EmojiconEditText mChatTextEdit; @BindView(R.id.send_message_button) ImageView mSendMessageButton; @BindView(R.id.message_list) RecyclerView mRecyclerView; @BindView(R.id.send_panel) View mSendPanel; public ViewHolder(View view) { super(view); } } }
ChatMessagesViewController.java @ActivityScope public class ChatMessagesViewController extends SimpleViewController<ChatViewModel> { private final ChatAdapter mChatAdapter; @Nullable private ChatViewModel mChatViewModel; @Nullable private ViewHolder mViewHolder; @Inject public ChatMessagesViewController(ChatAdapter chatAdapter) { mChatAdapter = chatAdapter; } @Override public void attach(ViewModelContainer<ChatViewModel> container) { mChatViewModel = container.getViewModel(); mViewHolder = new ViewHolder(container.getView()); mViewHolder.mRecyclerView.setAdapter(mChatAdapter); mChatViewModel.getMessages().observe(container, data -> mChatAdapter.updateMessages(data)); } @Override public void detach() { ViewHolderUtil.unbind(mViewHolder); mViewHolder = null; mChatViewModel = null; } public class SendMessageViewHolder extends ViewHolder { @BindView(R.id.message_list) RecyclerView mRecyclerView; public ViewHolder(View view) { super(view); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(view.getContext()); linearLayoutManager.setReverseLayout(true); linearLayoutManager.setStackFromEnd(true); mRecyclerView.setLayoutManager(linearLayoutManager); } } }
LiveDataã®ããžãã¯ã«ããããªã¹ãã¯onStopãšonStartã®éã§æŽæ°ãããŸãããããã¯ãçŸæç¹ã§ã¯LiveDataãéã¢ã¯ãã£ãã§ããããæ°ããã¡ãã»ãŒãžãããã·ã¥ãããå¯èœæ§ãããããã§ãã

ããã«ãããããŒã¿ã¹ãã¬ãŒãžã®å®è£
ãã«ãã»ã«åã§ããã¯ã©ã¹éã®åŒã³åºãã®é åºãæç¢ºã«ãªããŸãã åŒã³åºãé åºãšã¯ã©ãããæå³ã§ããïŒ
ããšãã°ãMVPãåãäžããŸãã
PresenterãšViewã«ã¯çžäºã«ãªã³ã¯ãããããšãçè§£ãããŸãã Viewã¯ãã«ã¹ã¿ã ã€ãã³ããPresenterã«è»¢éããŸãã 圌ã¯äœããã®åœ¢ã§ããããåŠçããçµæãè¿ããŸãã ãã®çžäºäœçšã§ã¯ãããŒã¿ã¹ããªãŒã ãæç¢ºã«ãªããŸããã äž¡æ¹ã®ãªããžã§ã¯ãã¯çžäºã«æç€ºçãªãªã³ã¯ãæã£ãŠããããïŒãããŠãã€ã³ã¿ãŒãã§ãŒã¹ã¯ãã®æ¥ç¶ãåæãããå°ãæœè±¡åããã ãã§ãïŒãåŒã³åºãã¯äž¡æ¹ã®æ¹åã«é²ã¿ãViewãååçã§ããæ¹æ³ã«ã€ããŠè°è«ããŸãã äœã転éããäœãåŠçããããªã©ã ãªã© ãŸãããã®ç¹ã§ãå€ãã®å Žåããã¬ãŒã³ã¿ãŒã®ã¬ãŒã¹ãéå§ããŸãã
ãã®å ŽåããŠãŒã¶ãŒããŒã¿ãããŒã¿ããŒã¹ã«ãã£ãã·ã¥ãããããšã¯æããã§ãã ãã ãããã£ãã·ã¥ã¯éåæã§è¡ããããŠãŒã¶ãŒã®å¿çã¯ãããåä¿¡ããçŽåŸã«LiveDataã«éä¿¡ãããããããŸã£ããäŸåããŸããã
ããã¯ãã¹ãŠããã«ãã¹ã¬ããããããã¯ãŒã¯åŒã³åºããšã©ã®ããã«åéã«ãªããŸããïŒ
ãã¹ãŠã®ãããã¯ãŒã¯èŠæ±ã¯ãã¢ã¯ãã£ããã£ãŸãã¯ãã©ã°ã¡ã³ããžã®åç
§ãæããªãã¯ã©ã¹ã®ã³ã³ããã¹ãããååŸãããèŠæ±ããã®ããŒã¿ã¯ã°ããŒãã«ã¯ã©ã¹ã§åŠçããããããã¢ããªã±ãŒã·ã§ã³ã¹ã³ãŒãã«ãããŸãã ãããã³ã°ã¯ããªãã¶ãŒããŒãŸãã¯ä»ã®ãªã¹ããŒãä»ããŠãã®ããŒã¿ãåãåããŸãã ãããLiveDataãä»ããŠè¡ãããå ŽåãonPauseãšonStartéã®ãããã³ã°ã¯æŽæ°ãããŸããã
衚瀺ã®ã¿ã«é¢é£ããéãæäœïŒããŒã¿ããŒã¹ããã®ããŒã¿ã®ååŸãç»åã®ãã³ãŒãããã¡ã€ã«ãžã®æžã蟌ã¿ïŒã¯ãViewModelã³ã³ããã¹ãããè¡ãããRxãŸãã¯LiveDataãä»ããŠé«éåãããŸãã ãã£ã¹ãã¬ã€ãåäœæãããšããããã®æäœã®çµæã¯ã¡ã¢ãªã«æ®ããããã«ãããªãŒã¯ãçºçããããšã¯ãããŸããã
LiveDataãšViewModelã®çæã«ã€ããŠè©±ãå Žåãæ¬¡ã®ç¹ã匷調ã§ããŸãã
- LiveDataã¯ãonStartãšonStopã®éã§ã®ã¿ã¢ã¯ãã£ãã§ããã€ãŸããonSaveInstanceStateã®åŸã«æ©èœããŸãããã®åŸãFragmenManagerãšã®å¯Ÿè©±ã«æ³šæããå¿
èŠããããŸãã
- LiveDataãæäœããããã®ãªãã¬ãŒã¿ãäžè¶³ããŠãããRxããªãå Žåã¯ããªãå¶éãããŸãã
- ViewModelã¯ãã·ã¹ãã ãã¢ã¯ãã£ããã£ã匷å¶çµäºããªãã£ãå ŽåïŒã¢ã¯ãã£ããã£ãä¿æããªãïŒ ãã¢ã¯ãã£ããã£ã®åäœæã«èããããŸãããã€ãŸããéèŠãªããŒã¿ã®äžéšã¯LiveDataã«ã®ã¿ãã£ãã·ã¥ã§ããŸããã
- ViewModelã¯ãã¬ã¯ãªãšãŒã·ã§ã³ã«é¢é£ãããã¹ãŠã®ãã¹ãããããã©ã°ã¡ã³ãã®åé¡ãç¶æ¿ããŸãã
ãããã«
å®éãèšäºã«æžãããŠããããšã¯ãã¹ãŠåå§çã§æçœã«èŠããŸãããæãã·ã³ãã«ãªã¢ãŒããã¯ãã£ã®ååã«åŸãããšã§ãéçºè
ãã¢ããªã±ãŒã·ã§ã³ãäœæãããšãã«ééããæè¡çãªåé¡ã®ã»ãšãã©ã解決ã§ãããããKeep It SimpleãStupidã®ååãéçºã®äž»èŠãªãã®ã®1ã€ãšèŠãªããŸãã ãããŠãMVPãMVCããŸãã¯MVVMãšåŒã°ãããã®ã«é¢ä¿ãªããäž»ãªããšã¯ããªããããå¿
èŠãªã®ããã©ã®ãããªåé¡ã解決ã«åœ¹ç«ã€ã®ããçè§£ããããšã§ãã
https://developer.android.com/topic/libraries/architecture/guide.html
https://en.wikipedia.org/wiki/KISS_principle
https://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html
https://android.jlelse.eu/android-architecture-components-viewmodel-e74faddf5b94
http://hannesdorfmann.com/android/arch-components-purist