This is the 26th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
preface
In the previous article, we made a preliminary use of Room in Jetpack, but each time we manipulated the data, we needed an additional query. In this article, there will be an integration of Room and what we learned earlier.
No more words, just get started!
1, Room + ViewModel + LiveData
As is shown in
This is the official recommended architecture that we use,
- ViewModel and Repository interact
- Repository interacts with the corresponding database and network requests
On the basis of the previous article, the corresponding Room database related for the time being.
Since databases are associated with Repository, and Repository is associated with ViewModel, what does Repository look like?
1.1 StudentRepository
class StudentRepository {
var studentDao: StudentDao? = null
constructor(context: Context) {
valdatabase = MyDatabase.getInstance(context) studentDao = database!! .getStudentDao() }fun insertStudent(vararg student: Student?).{ studentDao!! .insertStudent(*student) }fun deleteStudent(vararg student: Student){ studentDao!! .deleteStudent(*student) }fun updateStudent(vararg student: Student){ studentDao!! .updateStudent(*student) }fun deleteAllStudents(a){ studentDao!! .deleteAllStudents() }fun getAllStudentsLive(a): LiveData<List<Student>> {
returnstudentDao!! .getAllStudentsLive() }fun queryAll(a): List<Student>? {
returnstudentDao!! .queryAll() } }Copy the code
As you can see, all previous operations on the Dao are moved to Repository, which is also simpler.
But here’s the thing:getAllStudentsLive()
The method returnsLiveData<List<Student>>
, LiveData collection!
Now what about the ViewModel?
1.2 StudentViewModel
class StudentViewModel(application: Application) : AndroidViewModel(application) {
// Initialize the corresponding Repository object
private val repository by lazy { StudentRepository(application) }
// Define the corresponding set of LiveData
private var liveDataStudent: LiveData<List<Student>>? = null
init {
liveDataStudent = repository.getAllStudentsLive()
Log.d("StudentViewModel"."init liveDataStudent ${liveDataStudent? .value? .size}")}private fun insertStudent(vararg student: Student) {
viewModelScope.launch(Dispatchers.Default) {
repository.insertStudent(*student)
}
}
private fun deleteStudent(vararg student: Student) {
viewModelScope.launch(Dispatchers.Default) {
repository.deleteStudent(*student)
}
}
private fun updateStudent(vararg student: Student) {
viewModelScope.launch(Dispatchers.Default) {
repository.updateStudent(*student)
}
}
private fun deleteAllStudents(a) {
viewModelScope.launch(Dispatchers.Default) {
repository.deleteAllStudents()
}
}
fun getAllStudentsLive(a): LiveData<List<Student>>? {
viewModelScope.launch(Dispatchers.Default) {
liveDataStudent = repository.getAllStudentsLive()
}
return liveDataStudent
}
// Here are the methods called by the DataBinding layout -------------------
fun mInsert(a) {
val s1 = Student("hqk".26)
val s2 = Student("Rose".18)
insertStudent(s1, s2)
}
fun mClear(a) {
deleteAllStudents()
}
fun mDelete(a) {
var s1 = Student(3)
deleteStudent(s1)
}
fun mUpdate(a) {
val s1 = Student(2."Jason".21)
updateStudent(s1)
}
}
Copy the code
We can also see that the ViewModel is associated with the Repository and the corresponding layout is bound to the ViewModel via DataBinding!
Note that the viewModelScope is used inside the ViewModel, so you need to add the following dependencies
implementation "Androidx. Activity: activity - KTX: 1.2.0"
implementation "Androidx. Fragments: fragments - KTX: 1.3.0"
Copy the code
Here’s how to use it:
1.3 mainActivity
class MainActivity : AppCompatActivity() {
private var adapter: StudentRecyclerViewAdapter? = null
private var listStudent: ArrayList<Student> = ArrayList()
private var viewModel: StudentViewModel? = null
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_main)
val binding =
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
viewModel = ViewModelProvider(this)[StudentViewModel::class.java]
binding.studentViewModel = viewModel
binding.lifecycleOwner = this
// val recycleView = findViewById
(R.id.recycleView)
binding.recycleView.layoutManager = LinearLayoutManager(this)
adapter = StudentRecyclerViewAdapter(listStudent)
binding.recycleView.adapter = adapter
// Listen on the corresponding LiveData, when the database data changes, will be active callback notification!viewModel!! .getAllStudentsLive()!! .observe(this, androidx.lifecycle.Observer {
Log.d("StudentViewModel"."main it ${it.size}") adapter!! .students = it adapter!! .notifyDataSetChanged() }) } }Copy the code
Get the LiveData via ActivityMainBinding and add the logic. Use getAllStudentsLive to get the LiveData and listen on the LiveData set via Observe.
The DataBinding for Item is an ItemBinding. The DataBinding for Item is an ItemBinding.
Finally, let’s see how it works
Here we see that the data is automatically loaded with each operation, without manual query!
conclusion
Well, that’s the end of this optimization! In the next installment, we’ll cover Room upgrades and pre-fills!