[Android] MVVM 완전정복 (1)

CNH·2023년 5월 29일

개발

목록 보기
13/17

예전에 학교 프로젝트에서 MVVM과 RxJava을 사용해 본 적이 있었다. 내가 아니고 내 팀원이.. 그 당시에는 내가 할 수 있었던 건 레이아웃 그리기 정도였기 때문에 어느 순간 코드를 이해하는 것을 멈출 수 밖에 없었다.
이번에 네부캠 8기를 지원하며 '개발을 잘 하기 위해 노력한 경험'에 대해서 써야하는데, 아직 지원 기간이 2주 정도 남아서 MVVM을 소재로 써보려고 한다.
우선 오랜만에 학교 프로젝트 코드를 보니 RxJava까지 섞여 있어 코드를 알아보기 힘들다..

그래서 우선 Firebase와 Java를 사용하여 MVVM을 연습해 보려고 한다. 많은 블로그와 유튜브를 통해 MVVM의 개념은 이미 학습했고, 간단한 코드를 통해 설계를 해보려고 한다.

1. 첫 시도

  1. 우선 Firebase 프로젝트 생성하고 아래처럼 더미데이터를 만들었다.

  2. 우선 다수의 블로그를 참고한 결과 MainActivity는 아래 같이 만들면 될 것 같다.

public class MainActivity extends AppCompatActivity {

    FirebaseFirestore db = FirebaseFirestore.getInstance();

    final String TAG = "MainActivity";
    ActivityMainBinding binding;
    MainViewModel mainViewModel;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        mainViewModel = new ViewModelProvider(this).get(MainViewModel.class);
        mainViewModel.init();
        binding.setLifecycleOwner(this);



        TextView name2 = findViewById(R.id.name2);
        TextView age2 = findViewById(R.id.age2);

        mainViewModel.name.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.d(TAG, "onChanged: 바뀌었음 : "+s);
            }
        });



    }
}
  1. Model에 해당하는 Repository도 아래처럼 만들면 될 거 같다.
public class MainRepository {


    FirebaseFirestore db = FirebaseFirestore.getInstance();

//    MutableLiveData<String> name = new MutableLiveData<>("");
//    MutableLiveData<String> age = new MutableLiveData<>("");

    final String TAG = "MainRepository";

    public MutableLiveData<String> getName(){
        DocumentReference docRef = db.collection("Members").document("number1");
        MutableLiveData<String> name = new MutableLiveData<>("");
        docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                        Log.d(TAG, "DocumentSnapshot data: " + document.getData());
                        
						//처음에 여기서 return document.getData().get("Name") 이런 식으로 했는데 onComplete 메소드가 void라 return을 할 수 었다고 했다.
                        //어떻게 해야하나 하다가 안드로이드펍에 질문을 하여 답을 얻었다.
                        name.postValue(document.getData().get("Name")+"");

                    } else {
                        Log.d(TAG, "No such document");
                    }
                } else {
                    Log.d(TAG, "get failed with ", task.getException());
                }
            }
        });

        return name;
    }

}

안드로이드 펍 에서 질문을 남겼고 답변을 얻었다. 이렇게 하면 onComplete가 비동기처리가 되어 있어 마지막에 return될 때는 빈 값이 return될 줄 알았는데 비동기가 아니었나보다. 정상적으로 데이터가 return됐다.

  1. ViewModel이 가장 어렵고 지금도 이해가 잘 안 가는데
package com.example.hyodo_c_practice;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class MainViewModel extends ViewModel {

    MutableLiveData<String> name;
    MutableLiveData<String> age;

    MainRepository mainRepository = new MainRepository();

    public void init(){
        name = mainRepository.getName();
    }

//    public void getNameData(){
//        mainRepository.getName();
//    }

}

이렇게 하긴 했는데 뭔가 내가 핵심을 놓치고 있는 것 같다.. 우선 위에서 언급했던 팀원의 말을 들어보니 MVVM을 사용한다고 해서 Firebase의 데이터가 바뀔 시 자동으로 View에 데이터가 바뀌지는 않는다고 한다.. 이렇게 하면 정상 실행은 되며 가로모드로 바꿀 시 새로 데이터가 업데이트가 되긴 하는데, 이게 MVVM을 사용해서 어떤 이점이 있는 건지 모르겠다.. 애초에 내가 지금 한 게 뭔지도 모르겠다..
나는 화면 가로모드 전환 때문에 MVVM을 사용한다고 스토리를 만드는 거기 때문에, 아예 새롭게 firebase없이 프로젝트를 만들어보고자 한다.

profile
끄적끄적....

0개의 댓글