『Android Java』の【ROOM】について 2/2


今回はAndroid開発にてDBを楽に扱える【ROOM】の紹介2/2です。
前回(2022/4/18) ⇒ 『Android Java』の【ROOM】について 1/2

※Android開発には『Kotlin』もあるのですが今回は『Java』を使用しています。

■リポジトリを作成する

DAOを作成すると次に、リポジトリを作成します。
リポジトリとは、複数のデータソースへのRepositoryアクセスを抽象化します。
リポジトリはアーキテクチャコンポーネントライブラリの一部ではありませんが、コードの分離とアーキテクチャのベストプラクティスとして推奨されています。Repositoryクラスは、アプリケーションの残りの部分へのデータアクセスのためのクリーンなAPIを提供します。

package ○○.model;

import android.app.Application;
import android.util.Log;

import androidx.lifecycle.LiveData;

import java.util.List;

import ○○.db.AppDatabase;
import ○○.db.user_table.User;
import ○○.db.user_table.UserDao;

public class UserRepository {
    private UserDao mUserDao;
    private LiveData<User> mLoginUser;
    private int flag = 0;
    //コンストラクタ
    public UserRepository(Application application) {
        AppDatabase db = AppDatabase.getDatabase(application);
        mUserDao = db.userDao();
    }
    //ログインしているユーザーを取得する
    public LiveData<User> getLoginUser(String name, String pass){
        mLoginUser = mUserDao.getLoginUser(name,pass);
        return mLoginUser;
    }
    //ユーザーを追加する
    public void insert(User user){
        AppDatabase.databaseWriteExecutor.execute(() -> {
            mUserDao.insertAcount(user);
        });
    }
}

■View Modelを作成する

リポジトリの次に、View Modelを作成していきます。
UIにデータを提供し、構成の変更に耐えることです。
ViewModelは、リポジトリとUIの間のコミュニケーションセンターとして機能します。ViewModelを使用して、フラグメント間でデータを共有することもできます。
ViewModelは ライフサイクルライブラリの一部です。

package ○○.viewmodel.user;

import android.app.Application;

import androidx.lifecycle.AndroidViewModel;

import ○○.db.user_table.User;
import ○○.model.Common;
import ○○.model.UserRepository;


public class UserDataViewModel extends AndroidViewModel {
    private UserRepository mRepository;

    public UserDataViewModel (Application application) {
        super(application);
        mRepository = new UserRepository(application);
    }

    //リポジトリにユーザー追加の処理を依頼する。
    public void insert(String name,String pass) {
        User user = new User(name,pass);
        mRepository.insert(user);
    }

    public void logout(Common common) {
        common.setId(0);
        common.setName(null);
    }
}

■Viewを作成する

次にViewを作成していきます!
Viewはその名の通り、フロント画面となります。
Viewは好きに自由に作ってください!

■初期データを登録する

最初のアクセスにてDBの中身を作ることもできるんです!
前回の最後に作成したRoomDatabaseに以下を追加していきます。

    private static RoomDatabase.Callback sRoomDatabaseCallback = new RoomDatabase.Callback(){
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);

            databaseWriteExecutor.execute(() -> {
                UserDao udao = INSTANCE.userDao();

                User userInfo = new User("User","Sample");
                udao.insertAcount(userInfo);
                User userInfo = new User("GustUser","password");
                udao.insertAcount(userInfo);
                User userInfo = new User("abridge","password");
                udao.insertAcount(userInfo);
            });
        }
    };

■Activityを作成する

最後にActivityを作ります。
Activityの中で、LiveModelとの接続すれば完成です!!
(※UserのDBを作成しましたので、ログイン画面の実装をしたいと思います。)

package abridge.example.vocabularybooks.view.login;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import ○○.viewmodel.user.LoginViewModel;

public class LoginActivity extends AppCompatActivity implements View.OnClickListener {

    private LoginViewModel loginViewModel;
    private ProgressBar progressBar;
    private Common common;
    Button loginButton;
    Button gustlogin;
    EditText username;
    EditText password;
    TextView errortext;

    //Activityの作成処理
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);//親クラスの実行
        setTheme(R.style.AppTheme_NoTitleBar);//タイトルバーの非表示
        setContentView(R.layout.activity_login);//表示する画面の設定:ログイン画面
        common = (Common) this.getApplication();//APPLICATIONクラスの読み込み
        loginViewModel = new ViewModelProvider(this).get(LoginViewModel.class);//LiveDataクラスとの接続

        //UIの読み込み:ボタンやテキスト関連
        loginButton = (Button) findViewById(R.id.loginButton);
        gustlogin = (Button) findViewById(R.id.gustLogin);
        progressBar = findViewById(R.id.progressbar);
        username = (EditText) findViewById(R.id.userName);
        password = (EditText) findViewById(R.id.password);
        errortext = (TextView) findViewById(R.id.errorText);
        progressBar.setVisibility(android.widget.ProgressBar.INVISIBLE);
        loginButton.setOnClickListener(this);
        gustlogin.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.loginButton://ログインボタン押下時
                String input_name = String.valueOf(username.getText());
                String input_pass = String.valueOf(password.getText());
                //DB接続時にインジケーターの表示
                progressBar.setVisibility(android.widget.ProgressBar.VISIBLE);
                if (textcheck(input_name,input_pass)) {//空欄チェックが通ると下を実施
                    // getUserFlashCard()によって返されるLiveData
                    loginViewModel.getLoginUser(input_name,input_pass).observe(this, loginUser -> {
                        if(loginUser != null){
                            common.setId(loginUser.getUser_id());
                            common.setName(loginUser.getUser_name());
                            // MainActivityに遷移させる
                            Intent intent = new Intent(getApplication(), MainActivity.class);
                            intent.putExtra("Dialogflag",1);
                            startActivity(intent);
                            finish();
                        }else{
                            errortext.setText("※ユーザ名 または パスワードが間違っています");
                        }
                        progressBar.setVisibility(android.widget.ProgressBar.INVISIBLE);//インジケーターの非表示
                    });
                }
            break;
            case R.id.gustLogin://ゲストログインボタン押下時
                //DB接続時にインジケーターの表示
                progressBar.setVisibility(android.widget.ProgressBar.VISIBLE);
                //getUserFlashCard()によって返されるLiveData
                loginViewModel.getLoginUser("Sample","Sample").observe(this, loginUser -> {
                    if(loginUser != null){
                        common.setId(loginUser.getUser_id());
                        common.setName(loginUser.getUser_name());
                        // MainActivityに遷移させる
                        Intent intent = new Intent(getApplication(), MainActivity.class);
                        intent.putExtra("Dialogflag",1);
                        startActivity(intent);
                        finish();
                        progressBar.setVisibility(android.widget.ProgressBar.INVISIBLE);//インジケーターの非表示
                    }
                });
            break;
        }
    }

    public boolean textcheck(String username,String password){
        if (username.isEmpty() || password.isEmpty()) {
            errortext.setText("※ユーザ名 と パスワードは必須項目です");
            return false;
        } else {
            errortext.setText("");//エラーメッセージ欄のクリア。
            return true;
        }
    }
}

■データに接続する

アプリを起動すると、そのままDBが作られるので、ログインに成功するはずです!

以上で、『Android Java』の【ROOM】について2/2 終了となります。
ぜひ、AndroidのアプリでDBを扱う時がありましたら、【ROOM】を使用してみてください。