从零开始:使用Jetpack组件搭建自己的Android数据列表应用
2023-03-04 19:55:55
使用 Jetpack 架构组件开发高性能 Android 应用程序
简介
在当今快节奏的移动应用开发领域,构建健壮、可维护和高性能的应用程序至关重要。为了应对这一挑战,Google 为 Android 开发人员提供了一系列强大的工具:Jetpack 架构组件。这些组件旨在帮助开发者管理数据、简化 UI 交互并提高应用程序的整体性能。
了解 Jetpack 架构组件
Jetpack 架构组件是一组库,包括以下关键组件:
- Room: 轻量级数据库库,简化了与 SQLite 数据库的交互。
- ViewModel: 用于管理 UI 逻辑和数据的 UI 控制器。
- LiveData: 数据观察者,可确保在数据发生变化时更新 UI。
创建 Android 应用程序:使用 Room、ViewModel 和 LiveData
为了展示 Jetpack 架构组件的力量,我们将创建一个简单的 Android 应用程序,从 SQLite 数据库中检索数据并显示在一个列表中。
1. 创建项目
使用 Android Studio 创建一个新的 Android 项目。
2. 添加依赖项
在项目的 build.gradle 文件中添加以下依赖项:
implementation "androidx.room:room-runtime:2.3.0"
implementation "androidx.room:room-ktx:2.3.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
3. 创建数据库
创建一个名为 WordDatabase 的 Room 数据库类,它定义了数据库架构并生成访问数据库的代码。
4. 创建数据访问对象 (DAO)
创建一个名为 WordDao 的 DAO 接口,它定义了对数据库进行操作的方法,例如插入、查询和删除数据。
5. 创建实体类
创建一个名为 Word 的实体类,它定义了数据库中每条数据的结构。
6. 创建 ViewModel
创建一个名为 WordViewModel 的 ViewModel,它负责管理数据并与 UI 进行通信。
7. 创建 Repository
创建一个名为 WordRepository 的 Repository,它负责从数据库中获取数据并存储数据到数据库中。
8. 创建 Activity
创建一个名为 MainActivity 的 Activity,它负责显示数据列表并允许用户添加新的数据到数据库中。
9. 创建布局文件
创建一个名为 activity_main.xml 的布局文件,它定义了 MainActivity 的 UI。
10. 创建列表适配器
创建一个名为 WordListAdapter 的列表适配器,它负责将数据显示在 RecyclerView 中。
代码示例:
WordDatabase.kt
@Database(entities = [Word::class], version = 1)
abstract class WordDatabase : RoomDatabase() {
abstract fun wordDao(): WordDao
companion object {
@Volatile
private var INSTANCE: WordDatabase? = null
fun getDatabase(context: Context): WordDatabase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
WordDatabase::class.java,
"word_database"
).build()
INSTANCE = instance
return instance
}
}
}
}
WordDao.kt
@Dao
interface WordDao {
@Insert
fun insert(word: Word)
@Query("SELECT * FROM word_table ORDER BY word ASC")
fun getAllWords(): LiveData<List<Word>>
@Delete
fun delete(word: Word)
}
Word.kt
@Entity(tableName = "word_table")
data class Word(@PrimaryKey @ColumnInfo(name = "word") val word: String)
WordViewModel.kt
class WordViewModel(private val repository: WordRepository) : ViewModel() {
val allWords: LiveData<List<Word>> = repository.getAllWords()
fun insert(word: Word) {
repository.insert(word)
}
fun delete(word: Word) {
repository.delete(word)
}
}
WordRepository.kt
class WordRepository(private val wordDao: WordDao) {
val allWords: LiveData<List<Word>> = wordDao.getAllWords()
fun insert(word: Word) {
wordDao.insert(word)
}
fun delete(word: Word) {
wordDao.delete(word)
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: WordViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProviders.of(this).get(WordViewModel::class.java)
val adapter = WordListAdapter(this)
recyclerView.adapter = adapter
viewModel.allWords.observe(this, Observer { words ->
adapter.submitList(words)
})
fab.setOnClickListener {
val word = Word("Hello")
viewModel.insert(word)
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_margin="16dp"
android:src="@android:drawable/ic_input_add" />
</LinearLayout>
WordListAdapter.kt
class WordListAdapter(private val context: Context) : ListAdapter<Word, WordListAdapter.WordViewHolder>(DIFF_CALLBACK) {
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Word>() {
override fun areItemsTheSame(oldItem: Word, newItem: Word): Boolean {
return oldItem.word == newItem.word
}
override fun areContentsTheSame(oldItem: Word, newItem: Word): Boolean {
return oldItem.word == newItem.word
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WordViewHolder {
val itemView = LayoutInflater.from(context).inflate(R.layout.item_word, parent, false)
return WordViewHolder(itemView)
}
override fun onBindViewHolder(holder: WordViewHolder, position: Int) {
val word = getItem(position)
holder.textView.text = word.word
}
class WordViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}
常见问题解答
1. 什么是 Jetpack 架构组件?
Jetpack 架构组件是一组工具,帮助 Android 开发人员构建健壮、可维护和高性能的应用程序。
2. 为什么应该使用 Jetpack 架构组件?
Jetpack 架构组件简化了数据管理、UI 交互和应用程序整体性能。
3. Jetpack 架构组件的主要组件是什么?
Jetpack 架构组件的主要组件包括 Room(数据库库)、ViewModel(UI 控制器)和 LiveData(数据观察者)。
4. Room 如何帮助我管理数据库?
Room 提供了一个轻量级 API,用于与 SQLite 数据库进行交互,它消除了编写复杂 SQL 查询的需要。
5. ViewModel 在 Jetpack 架构组件中扮演什么角色?
ViewModel 是一个 UI 控制器,它管理数据并与 UI 通信,确保数据在 Activity 或 Fragment 生命周期变更后仍然存在。