PROGRAMMING
Android Kotlin
- UiState の値が変わっても UI が変化しない?
- Room での SQL いろいろ
- Room を使うための Application Database Dao Repository ViewModel
- Room を使うための事前準備 (設定)
- 外部(共有)ストレージの Media ファイルへのアクセス
- 外部(共有)ストレージの Document ファイルへのアクセス
- 内部(App固有)ストレージへのアクセス
javascript
- ページャーを作る(簡易版)
- ページャーを作る 4/4
(クロスブラウザ対策)
(ページャー表示用メソッド)
(ページャーの使い方) - ページャーを作る 3/4
(イベント登録) - ページャーを作る 2/4
(スタイルの設定) - ページャーを作る 1/4
(ページャー用関数を準備)
(各要素を生成) - 自作カレンダーを作る 6/6
(11.~14.各種メソッド)
(15.簡単な使い方) - 自作カレンダーを作る 5/6
(09.祝休日の判定)
(10.閏年の判定) - 自作カレンダーを作る 4/6
(08.イベントの設定) - 自作カレンダーを作る 3/6
(07.スタイルの設定) - 自作カレンダーを作る 2/6
(05.カレンダーのマスのみ作成)
(06.各マスへ年月・日付を埋め込み) - 自作カレンダーを作る 1/6
(01.カレンダーの基を準備)
(02.各月の日数や年月日の区切り文字)
(03.前月・次月指定時の処理)
(04.前月・次月部分の年月を算出) - JS-Image-Resizerを使って画像を高画質で縮小
- ファイルを作成しローカルに保存
- モーダルウィンドウをクラス化
- ストップウォッチを作る
- XMLHttpRequest Lebel2を試してみる
- jQuery:Tableで親・子・兄弟要素を取得
- 文字列をセパレータ文字で分割し配列で返す関数
- forループのカウンタを使用している関数の定義
- クロージャの使いどころ
- JSONPでクロスドメイン
- AjaxでJSON形式のデータを扱う
- jsファイルからjsファイルを呼び出す
- jQuery:モーダルウィンドウを作ってみる
PHP
Java
- IntelliJ.Gradle.JavaFX(6) プラグイン org.beryx.jlink を使ってみる
- IntelliJ.Gradle.JavaFX(5) NSISでインストーラーを作る
- IntelliJ.Gradle.JavaFX(4) exewrapで実行可能jarをexe化する
- IntelliJ.Gradle.JavaFX(3) Jlink でカスタム JRE を作る
- IntelliJ.Gradle.JavaFX(2) すべての依存対象を含んだ Fatjar を作る
- IntelliJ.Gradle.JavaFX(1) アプリケーションを作る
- javaのコンパイルと実行
- イメージを回転する
- Exif情報を簡単に取得できるライブラリ
- 高画質で画像縮小
- JDBCによるデータベース操作
Room を使うための Application Database Dao Repository ViewModel
アプリを作っているとデータベースの利用は必須だと思います。
いつも Room で使用する色んなクラスの依存関係をメモっておくことにしました。
≪開発環境≫
windows11
andriod studio Ladybug
インスタンス生成の流れ
Room を使うための各クラスはそれぞれ依存関係にあるため、依存されているクラスを先にインスタンスする。
各ファイル | インスタンスの場所 | インスタンスの順序 |
Application | AndroidManifest | 1 |
Database | Application | 2 |
Dao | Application | 3 |
Repository | Application | 4 |
ViewModel | Activity | 5 |
AndroidManifest
AndroidManifest の name に Application を登録し自動的にインスタンスされるようにする。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".SampleApplication"
android:allowBackup="true"
:
:
Application
Application 内で Database → Dao → Repository の順にインスタンスする。
// AndroidManifest.xml に登録必要
class SampleApplication : Application() {
// データベースのインスタンスを作成 Database が全てのクラスから使えるようになる
val database by lazy { SampleDatabase.getInstance(this) }
// Daoをインスタンス化してリポジトリのインスタンス作成
val repository by lazy { SampleRepository(database.sampleDao()) }
}
Database
Database クラスは abstract(抽象クラス)であり、Room が実装を自動的に行う
@Database(
version = 1,
entities = [Users::class, Groups::class],
exportSchema = false,
// autoMigrations = [
// AutoMigration (from = 1, to = 2)
// ]
)
abstract class SampleDatabase : RoomDatabase() {
// この関数を実行することで Room が Dao を使えるように実装してくれる
abstract fun SampleDao(): SampleDao
/**
* companionオブジェクトはクラスのインスタンス化無しで、
* データベースを作成または取得するためのメソッドへのアクセスを可能にする。
* このクラスの唯一の目的はデータベースを提供することだけなので、これをインスタンス化する理由はない。 */
companion object {
/**
* データベースが作成された時点でINSTANCE変数にはデータベースの参照を持たせる。
* これにより、繰り返し負荷のかかるデータベースへの接続を開く必要がなくなる。 */
@Volatile
private var INSTANCE: SampleDatabase? = null
fun getInstance(context: Context): SampleDatabase {
// synchronizedは一度に1つの実行スレッドだけがこのコードブロックに入ることができる
// データベースが 1 回だけ初期化されるようにする
synchronized(this) {
var instance = INSTANCE
// データベースが存在するときは、存在するデータベースを返し、存在しない場合は、データベースを作成する
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
SampleDatabase::class.java,
"Sample_database" // database file name
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
Dao
Dao のインスタンスは Application 内で Repository インスタンス時に済んでいる。
@Dao
interface SampleDao {
:
:
}
Repository
リポジトリは Dao のインスタンスが必要だが、どちらも Application 内で作成済み。
class SampleRepository(private val dao: SampleDao) {
:
:
}
ViewModel
ViewModel では companion object で viewModelFactory を定義し Activity でインスタンスできるようにする。
class MyViewModel(private val repo: SampleRepository) : ViewModel() {
:
:
/** 引数付きの ViewModel を生成するための Factory
* Activity にてこれを使用し Viewmodel のインスタンスを作成 ================================ */
companion object {
val factory = viewModelFactory {
initializer {
// [APPLICATION_KEY] は ViewModel から Application クラスのインスタンスを参照できる
val application = (this[APPLICATION_KEY] as SampleApplication)
// 引数をセット
MyViewModel(application.repository)
}
}
}
}
Activity
ViewModel 内の viewModelFactory を使用し Activity でインスタンスする。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
SampleAppTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
// 引数あり(room使用のため)の ViewModel を準備
val owner = LocalViewModelStoreOwner.current
owner?.let {
val viewModel: MyViewModel = viewModel(factory = MyViewModel.factory)
MainContent(viewModel)
}
}
}
}
}
}
@Composable
fun MainContent(
viewModel: MyViewModel
) {
:
:
}
まとめ
Room を使うための準備は gradle の設定や沢山のクラス作成など面倒ですが
パターンをメモっておけば楽に進めれると実感しました。