リポジトリを使用したリポジトリ


リポジトリパターンは、アプリケーション内の複数のデータソースを隠すために使用される抽象化です.アプリケーション内のデータは、内部のデータベース、またはWeb APIのような外部サービスから来ている可能性があります.
このパターンは採用され、Androidアプリケーションを開発する際に広く使用され、アプリケーションの作成にも推奨されます.
Android上の一般的なモバイルアプリケーションアーキテクチャを次の図に示します.

この図から取得できるのは次のとおりです.
我々の活動/断片は1つまたは複数のViewModelの複数のインスタンスを持つかもしれないか、または持っていないかもしれません、各々のViewモデルは特定の倉庫に依存を持ちます、この倉庫は複数の表示モデルによって共有されることができます.
リポジトリは、情報を取得する場所からデータソースを知っています.この場合、リポジトリは、Webサービスに通信するために、レトロライトによって提供されるモデル、SQLiteの上にあるレイヤー、およびサービスインターフェイスを知っています.
各レイヤーは以下の層を知っているだけです.ViewModelはリポジトリと対話する人を知りません.
具体的な実装例をあげましょう.
我々は、サンプルの活動は、editTextリマインダーを追加し、アラームを追加するには、ボタンを起動します.

createreminderactivity


class CreateReminderActivity : AppCompatActivity() {

    val viewModel: CreateReminderViewModel by lazy {
        val app = application as ReminderApp
        val viewModelProviderFactory =
            CreateReminderViewModelProviderFactory(
                app,
                intent
            )
        ViewModelProvider(
            this,
            viewModelProviderFactory
        )[CreateReminderViewModel::class.java]
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.createreminderactivity)

        val reminderEditText: EditText = findViewById(R.id.reminderEditTextView)
        val createReminderButton: Button = findViewById(R.id.createReminderButton)


        createReminderButton.setOnClickListener {
            createReminder(
                text = reminderEditText.text.toString()
            )
        }
    }

    private fun createReminder(text: String) {
        if (text.isEmpty()) {
            showToast(message = "Reminder text field is empty")
        } else {
            viewModel.createReminder(text = text)
        }
    }

    private fun showToast(message: String) {
        ...
    }
}

アプリケーション


class ReminderApp : Application() {

    companion object {
        lateinit var retrofit: Retrofit
        lateinit var reminderDb: ReminderDb
    }

    override fun onCreate() {
        super.onCreate()
        reminderDb = Room
            .databaseBuilder(
                applicationContext,
                ReminderDb::class.java,
                "Reminder-Db"
            )
            .build()

        retrofit = Retrofit.Builder()
            .baseUrl(REMINDERS_API_HOST)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
}

ビューファクトリ



class CreateReminderViewModelProviderFactory(val app: ReminderApp, val intent: Intent) :
    ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        val reminderDao = ReminderApp.reminderDb.reminderDao()
        val reminderService = ReminderApp.retrofit.create(ReminderService::class.java)
        val reminderRepository = ReminderRepository(
            reminderDao = reminderDao,
            reminderService = reminderService
        )
        val viewModel = CreateReminderViewModel(reminderRepository)
        return viewModel as T
    }
}

ビューモデル


class CreateReminderViewModel(private val reminderRepository: ReminderRepository) : ViewModel() {

    fun createReminder(text: String) =
        viewModelScope.launch {
            reminderRepository.createReminder(text = text)
        }
}
createReminderは、Coooutineを起動するためにViewModelScopeを使用します.
ViewModelがクリアされるならば、この範囲で起動されるどんなCOOTOINEも自動的にキャンセルされます.ここでは、ViewModelがアクティブな場合にのみ実行する必要がある場合について説明します.たとえば、レイアウトのデータを計算している場合は、ViewModelがクリアされている場合は、そのリソースを使用しないように自動的にキャンセルされます.

倉庫


class ReminderRepository(
    private val reminderService: ReminderService,
    private val reminderDao: ReminderDao
) {

    suspend fun getReminders(): LiveData<List<Programme>> = liveData {
        emitSource(reminderDao.getReminders())
        val reminders = reminderService.getReminders().toReminders()
        reminderDao.createReminder(*reminders.toTypedArray())
    }
    ...

    suspend fun createReminders(text: String): Reminder {
        val reminderToBeCreated = ReminderInputModelDto(text = text)
        val reminder = reminderService.createReminder(reminderToBeCreated).toReminder()
        reminderDao.createReminder(reminder)
        return reminder
    }

理研台


@Dao
interface ReminderDao {

    @Query("SELECT * FROM REMINDER")
    fun getAllReminders(): LiveData<List<Reminder>>

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun createReminder(vararg reminders: Reminder)

}

追憶


interface ReminderService {

    @GET("reminders")
    suspend fun getReminders(): RemindersOutputModelDto

    @POST("reminders")
    suspend fun createReminder(@Body reminder: ReminderInputModelDto): ReminderOutputModelDto

}
この記事では、Androidアプリケーションを設計する際に推奨されるアプローチの実装を試みます.