[Android]Room を使ったサンプル
AndroidのRoomの勉強のために作成したサンプルを残しておこうと思う。
[勉強のために参考しにしたサイトを下記の通り。
JavaによるAndroid非同期処理の基本 (1/3):CodeZine(コードジン)
AndroidのRoomライブラリを用いたDB非同期処理をHandlerで書いてみた - OPTiM TECH BLOG
[Android/Java]Roomでローカルデータベースを操作する - Qiita
Room を使用してローカル データベースにデータを保存する | Android デベロッパー | Android Developers
[開発ツール]
Android Studio 4.1.3
[画面]
[ソース]
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toTopOf="@+id/linearLayout" app:layout_constraintTop_toTopOf="parent"/> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="0dp" android:layout_margin="5dp" android:layout_weight="1" android:layout_marginBottom="683dp" android:orientation="horizontal" app:layout_constraintBottom_toBottomOf="parent" tools:layout_editor_absoluteX="5dp"> <EditText android:id="@+id/editTextUser" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:autofillHints="@string/hint_addUser" android:hint="@string/hint_addUser" android:inputType="textMultiLine" /> <Button android:id="@+id/buttonAddUser" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="end" android:onClick="onClickAddUserButton" android:text="登録" /> <Button android:id="@+id/buttonDispAllUser" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="end" android:insetLeft="5dp" android:onClick="onClickDispAllUserButton" android:text="全件表示" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package jp.co.hoshisoft.roomsample; import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.os.Bundle; import android.os.Looper; import android.util.Log; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ListView; import java.util.Iterator; import java.util.List; import jp.co.hoshisoft.roomsample.db.User; import jp.co.hoshisoft.roomsample.module.AppDataManager; import jp.co.hoshisoft.roomsample.module.AppHandler; public class MainActivity extends AppCompatActivity { private AppDataManager appDataManager; private AppHandler appHandler; private ArrayAdapter<String> userListAdapter; public MainActivity() { } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); appDataManager = new AppDataManager(this); appHandler = new AppHandler(Looper.getMainLooper(), this); appDataManager.setAppHandler(appHandler); userListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1); ListView listView = (ListView) findViewById(R.id.listView1); listView.setAdapter(userListAdapter); } public void onClickAddUserButton(View view) { EditText editText = findViewById(R.id.editTextUser); String inputName = editText.getText().toString(); editText.setText(""); InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); if (inputName.length() != 0) { User user = new User(); user.setName(inputName); user.setCreatedAt(System.currentTimeMillis()); appDataManager.insert(user); } } public void onClickDispAllUserButton(View view) { appDataManager.readAll(); } // public void onClickClearAllUserButton(View view) // { // userListAdapter.clear(); // } // public void onClickQuitButton(View view) // { // this.finish(); // } public void inserUserCompleted(User user) { userListAdapter.add(user.getName()); } public void readUserCompleted(List<User> allUser) { userListAdapter.clear(); Iterator it = allUser.iterator(); while (it.hasNext()) { User user = (User)it.next(); userListAdapter.add(user.getName()); } } }
AppRoomDatabase.java
package jp.co.hoshisoft.roomsample.db; import android.content.Context; import androidx.room.Database; import androidx.room.Room; import androidx.room.RoomDatabase; @Database(entities = {User.class}, version = 1, exportSchema = false) public abstract class AppRoomDatabase extends RoomDatabase { public abstract UserDao UserDao(); private static AppRoomDatabase appRoomDatabase; public static AppRoomDatabase getDatabase(final Context context) { if (appRoomDatabase == null) { synchronized (AppRoomDatabase.class) { if (appRoomDatabase == null) { appRoomDatabase = Room.databaseBuilder(context.getApplicationContext(), AppRoomDatabase.class, "user_database") .build(); } } } return appRoomDatabase; } public void closeDatabase() { if (appRoomDatabase.isOpen()) { appRoomDatabase.close(); } appRoomDatabase = null; } }
User.java
package jp.co.hoshisoft.roomsample.db; import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.PrimaryKey; @Entity public class User { @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "user_id") public int id; public String name; @ColumnInfo(name = "created_at") public Long createdAt; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getCreatedAt() { return createdAt; } public void setCreatedAt(Long createdAt) { this.createdAt = createdAt; } }
UserDao.java
package jp.co.hoshisoft.roomsample.db; import androidx.room.Dao; import androidx.room.Delete; import androidx.room.Insert; import androidx.room.Query; import androidx.room.Update; import java.util.List; @Dao public interface UserDao { @Query("SELECT * FROM user ORDER BY created_at") public List<User> loadAll(); @Query("SELECT * FROM user WHERE user_id = :id") public User loadById(int id); @Query("SELECT * FROM user WHERE user_id IN (:ids)") public List<User> loadAllByIds(int[] ids); @Insert public long insertUser(User user); @Update public void updateUser(User user); @Delete public void deleteUser(User user); @Query("DELETE FROM user") public void deleteAllUser(); @Query("DELETE FROM user WHERE user_id = :id") public void deleteById(int id); }
AppDataManager.java
package jp.co.hoshisoft.roomsample.module; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Message; import androidx.annotation.NonNull; import androidx.annotation.UiThread; import androidx.annotation.WorkerThread; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import jp.co.hoshisoft.roomsample.db.User; import jp.co.hoshisoft.roomsample.db.UserDao; import jp.co.hoshisoft.roomsample.db.AppRoomDatabase; public class AppDataManager { private static final int INSERT = 1; // private static final int UPDATE = 2; // private static final int DELETE = 3; // private static final int READ = 4; // private static final int DELETE_ALL = 13; private static final int READ_ALL = 14; private UserDao userDao; private AppRoomDatabase appRoomDatabase; private AppHandler appHandler; private List<User> allUser; // 非同期処理を行うworkerスレッド用のシングルスレッド。 private ExecutorService executorService = Executors.newSingleThreadExecutor(); public AppDataManager(Context context) { appRoomDatabase = AppRoomDatabase.getDatabase(context); userDao = appRoomDatabase.UserDao(); } public void setAppHandler(AppHandler appHandler) { this.appHandler = appHandler; } public void insert(User user) { BackgroundTask backgroundTask = new BackgroundTask(INSERT, userDao, user, appHandler); executorService.submit(backgroundTask); } // public void deleteAll() // { // BackgroundTask backgroundTask = new BackgroundTask(DELETE_ALL, userDao, null, appHandler); // executorService.submit(backgroundTask); // } // // public void delete(User user) // { // BackgroundTask backgroundTask = new BackgroundTask(DELETE, userDao, user, appHandler); // executorService.submit(backgroundTask); // } public void readAll() { BackgroundTask backgroundTask = new BackgroundTask(READ_ALL, userDao, null, appHandler); executorService.submit(backgroundTask); } public void closeDatabase() { appRoomDatabase.closeDatabase(); } }
BackgroundTask.java
package jp.co.hoshisoft.roomsample.module; import android.os.Handler; import androidx.annotation.WorkerThread; import java.util.List; import jp.co.hoshisoft.roomsample.db.User; import jp.co.hoshisoft.roomsample.db.UserDao; public class BackgroundTask implements Runnable { private static final int INSERT = 1; // private static final int UPDATE = 2; // private static final int DELETE = 3; // private static final int READ = 4; // private static final int DELETE_ALL = 13; private static final int READ_ALL = 14; private int type; private UserDao userDao; private User user; private final Handler handler; BackgroundTask(int type, UserDao userDao, User user, Handler handler) { this.type = type; this.userDao = userDao; this.user = user; this.handler = handler; } @WorkerThread @Override public void run() { //非同期処理を開始する。 switch (type) { case INSERT: long ret = userDao.insertUser(user); user.setId((int)ret); handler.sendMessage(handler.obtainMessage(INSERT, (Object)user)); break; // case DELETE: // userDao.deleteUser(user); // handler.sendMessage(handler.obtainMessage(DELETE, (Object)user)); // break; // case DELETE_ALL: // userDao.deleteAllUser(); // handler.sendMessage(handler.obtainMessage(DELETE_ALL)); // break; case READ_ALL: List<User> Alluser = userDao.loadAll(); handler.sendMessage(handler.obtainMessage(READ_ALL, (Object)Alluser)); break; default: break; } } }
AppHandler.java
package jp.co.hoshisoft.roomsample.module; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Message; import androidx.annotation.NonNull; import java.util.List; import jp.co.hoshisoft.roomsample.MainActivity; import jp.co.hoshisoft.roomsample.db.User; public class AppHandler extends Handler { private MainActivity activity; private static final int INSERT = 1; // private static final int UPDATE = 2; // private static final int DELETE = 3; // private static final int READ = 4; // private static final int DELETE_ALL = 13; private static final int READ_ALL = 14; public AppHandler(Looper looper, Context context) { super(looper); activity = (MainActivity)context; } @Override public void handleMessage(Message msg) { switch (msg.what) { case INSERT: activity.inserUserCompleted((User)msg.obj); break; // case DELETE: // activity.deleteUserCompleted((User)msg.obj); // break; // case DELETE_ALL: // activity.deleteAllUserCompleted(); // break; case READ_ALL: activity.readUserCompleted((List<User>)msg.obj); break; default: break; } } }
[build.gradleへ依存関係の追加]
build.gradleに、Roomを使用するための依存関係を追加
dependencies { def room_version = "2.2.6" implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" }