ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Android] MVVM 패턴 적용 - ACC 예제
    Android 2022. 10. 11. 23:01

    - DAO ? DB의 data에 접근하기 위한 객체 

     

     

    < viewmodel 적용 이전>

    Todo.class (Room)

    : id, title이 정의된 데이터

    package org.techtown.myapplication;
    
    import androidx.room.Entity;
    import androidx.room.PrimaryKey;
    
    @Entity //룸에서 사용할수 있는 entity
    public class Todo {
        @PrimaryKey(autoGenerate = true)
        private int id;
        private String title;
    
        public Todo(String title) {
            this.title = title;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        @Override
        public String toString() {
            return "Todo{" +
                    "id=" + id +
                    ", title='" + title + '\'' +
                    '}';
        }
    }

    TodoDao.interface

    : Todo에 접근하기 위한 데이터 접근 객체

    : 조회, 삽입 , 삭제등의 메서드를 정의함 getAll() -> Todo의 모든 값 조회

    : LiveData로 지정함

    package org.techtown.myapplication;
    
    import androidx.lifecycle.LiveData;
    import androidx.room.Dao;
    import androidx.room.Delete;
    import androidx.room.Insert;
    import androidx.room.Query;
    import androidx.room.Update;
    
    import java.util.List;
    
    //Todo에 접근하기 위한 Data access object
    @Dao
    public interface TodoDao {
        //Todo에 어떤 동작 제공할지 정의
        @Query("SELECT * FROM Todo")
        LiveData<List<Todo>> getAll();
    
        @Insert
        void insert(Todo todo);
    
        @Update
        void update(Todo todo);
    
        @Delete
        void delete(Todo todo);
    
    }

    AppDatabase.class

    : RoomDB 상속후 tododao 구체화

    package org.techtown.myapplication;
    
    import androidx.room.Database;
    import androidx.room.RoomDatabase;
    @Database(entities = {Todo.class}, version = 1)
    public abstract class AppDatabase extends RoomDatabase {
        public abstract TodoDao todoDao(); // todo조작
    }

     

    MainActivity.class

    : observe를 통해 값이 바뀌면 갱신함

    package org.techtown.myapplication;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.lifecycle.Observer;
    import androidx.lifecycle.ViewModelProvider;
    import androidx.room.Room;
    
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
        private EditText mTodoEditText;
        private TextView mResultTextview;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mTodoEditText = findViewById(R.id.todoEdit);
            mResultTextview = findViewById(R.id.result_text);
    
    
            final AppDatabase db = Room.databaseBuilder(this,AppDatabase.class,"todo-db")
                    .build();
    
            //UI 갱신
            db.todoDao().getAll().observe(this,todos -> {
                mResultTextview.setText(todos.toString());
            });
    
    
            // 버튼 클릭시 db에 insert
            findViewById(R.id.addBtn).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    new InsertAsyncTask(db.todoDao())
                            .execute(new Todo(mTodoEditText.getText().toString()));
                }
            });
        }
    
        private static class InsertAsyncTask extends AsyncTask<Todo, Void, Void> {
            private TodoDao mTodoDao;
    
            public InsertAsyncTask(TodoDao todoDao){
                this.mTodoDao = todoDao;
            }
            //Room을 비동기로 사용
            @Override
            protected Void doInBackground(Todo... todos) {
                mTodoDao.insert(todos[0]);
                return null;
            }
        }
    
    
    }

     

    < ViewModel 적용 후 >

    MainActivity.class

    : 원래는 db 선언, 버튼 클릭시 insert가 MainActivity에 선언되어 있었지만,

    UI와 기능을 분리하기 위해

    MainActivity에서 viewprovider를 선언하고 따로 선언된 MainViewModel의 메서드를 불러옴

    observe()로 변하는 ui를 관찰함

    package org.techtown.myapplication;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.lifecycle.Observer;
    import androidx.lifecycle.ViewModelProvider;
    import androidx.room.Room;
    
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
        private EditText mTodoEditText;
        private TextView mResultTextview;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mTodoEditText = findViewById(R.id.todoEdit);
            mResultTextview = findViewById(R.id.result_text);
    		
            //ViewModelPrivider로 ViewModel 사용 가능
            MainViewModel viewModel = new ViewModelProvider(this)
                    .get(MainViewModel.class);
    
            // getall시 결과가 변경될때마다 todo로 들어옴
            // 관찰하다가 ui 갱신
            viewModel.getAll().observe(this, new Observer<List<Todo>>() {
                @Override
                public void onChanged(List<Todo> todos) {
                    mResultTextview.setText(todos.toString());
                }
            });
    
            // 버튼 클릭시 db에 insert
            // 값이 안 바뀔수도 있는 경우엔 ui갱신을 하지 않아도 됨
            findViewById(R.id.addBtn).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    viewModel.insert(new Todo(mTodoEditText.getText().toString()));
    
    
    
                }
            });
        }
    
    
    //                원래 아래 코드를 onClick()에 썼다면 aac패턴에서는 onChanged안에 넣기
    //                mResultTextview.setText(db.todoDao().getAll().toString());
    
    }

     

    MainViewModel.class

    : 여기서 db선언, LiveData 선언, insert() 메서드 선언을 따로 해줌

    getAll() 을 호출하면 tododao의 getall을 호출해줌

    package org.techtown.myapplication;
    
    import android.app.Application;
    import android.os.AsyncTask;
    
    import androidx.annotation.NonNull;
    import androidx.lifecycle.AndroidViewModel;
    import androidx.lifecycle.LiveData;
    import androidx.lifecycle.ViewModel;
    import androidx.room.Room;
    
    import java.util.List;
    
    public class MainViewModel extends AndroidViewModel {
        private AppDatabase db;
        public MainViewModel(@NonNull Application application) {
            super(application);
    
                   db = Room.databaseBuilder(application, AppDatabase.class,"todo-db")
                   .build();
        }
    
            public LiveData<List<Todo>> getAll() {
                return db.todoDao().getAll();
            }
    
            public void insert(Todo todo) {
                new InsertAsyncTask(db.todoDao())
                        .execute(todo);
            }
    
        private static class InsertAsyncTask extends AsyncTask<Todo, Void, Void> {
            private TodoDao mTodoDao;
    
            public InsertAsyncTask(TodoDao todoDao){
                this.mTodoDao = todoDao;
            }
            @Override
            protected Void doInBackground(Todo... todos) {
                mTodoDao.insert(todos[0]);
                return null;
            }
        }
    //
    //    private AppDatabase db;
    //
    //    public MainViewModel(@NonNull Application application) {
    //        super(application);
    //        // db 객체 생성
    //       db = Room.databaseBuilder(application, AppDatabase.class,"todo-db")
    //               .build();
    //
    //        //.allowMainThreadQueries() //백그라운드 말고 메인 스레드에서 db사용
    //
    //    public LiveData<List<Todo>> getAll() {
    //            return db.todoDao().getAll();
    //        }
    //    public void insert(Todo todo) {
    //
    //        }
    //    }
    
    
    }
    

     -> MainActivity에는 ui관련 코드만 남게 됨

     

     

    <DataBinding 적용후>

     

    'Android' 카테고리의 다른 글

    [Android] DataBinding  (3) 2022.10.15
    [Android] MVVM 패턴 적용 - ACC  (0) 2022.10.10
Designed by Tistory.