亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

kotlin中的模塊化結(jié)構(gòu)組件及工作原理

 更新時間:2025年03月15日 10:04:43   作者:每次的天空  
本文介紹了Kotlin中模塊化結(jié)構(gòu)組件,包括ViewModel、LiveData、Room和Navigation的工作原理和基礎(chǔ)使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧

模塊化結(jié)構(gòu)組件包含ViewModel、LiveData、Room 和 Navigation ,我將講解它們的工作原理和基礎(chǔ)使用。

ViewModel 工作原理

  • 創(chuàng)建與存儲機(jī)制:當(dāng)調(diào)用 ViewModelProvider 的 get 方法獲取 ViewModel 實(shí)例時,ViewModelProvider 會先檢查 ViewModelStore 中是否已存在該類型的實(shí)例。若存在則直接返回,若不存在則使用 ViewModelProvider.Factory 創(chuàng)建新實(shí)例并存儲在 ViewModelStore 中。每個 Activity 和 Fragment 都有各自對應(yīng)的 ViewModelStore,用于管理其內(nèi)部的 ViewModel 實(shí)例。
  • 生命周期管理ViewModel 的生命周期與關(guān)聯(lián)的 Activity 或 Fragment 緊密相關(guān),但又有區(qū)別。在配置更改(如屏幕旋轉(zhuǎn))時,Activity 或 Fragment 會重新創(chuàng)建,而 ViewModelStore 會被保留,所以 ViewModel 實(shí)例也得以保留,從而保證數(shù)據(jù)的一致性。當(dāng) Activity 或 Fragment 被銷毀(非因配置更改)時,ViewModelStore 會調(diào)用 clear 方法,進(jìn)而調(diào)用 ViewModel 的 onCleared 方法,讓開發(fā)者可以在此進(jìn)行資源釋放操作。

ViewModel 通過 ViewModelStore 存儲實(shí)例,在配置更改時保留數(shù)據(jù),在關(guān)聯(lián)組件非配置更改銷毀時釋放資源。 

// 定義 ViewModel 類
import androidx.lifecycle.ViewModel
import androidx.lifecycle.MutableLiveData
class NewsViewModel : ViewModel() {
    // 定義 LiveData 存儲新聞列表
    private val _newsList = MutableLiveData<List<String>>()
    val newsList: LiveData<List<String>> = _newsList
    init {
        // 模擬從網(wǎng)絡(luò)或數(shù)據(jù)庫獲取新聞數(shù)據(jù)
        fetchNews()
    }
    private fun fetchNews() {
        // 這里可以替換為真實(shí)的網(wǎng)絡(luò)請求或數(shù)據(jù)庫查詢
        val mockNews = listOf("新聞1", "新聞2", "新聞3")
        _newsList.value = mockNews
    }
}
// 在 Activity 中使用 ViewModel
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
    private lateinit var newsViewModel: NewsViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView{"name":"GodelPlugin","parameters":{"input":"\"setContentView(R.layout.activity_main)\""}}<|FunctionExecuteEnd|><|FunctionExecuteResult|>setContentView(R.layout.activity_main)<|FunctionExecuteResultEnd|>
        // 獲取 ViewModel 實(shí)例
        newsViewModel = ViewModelProvider(this).get(NewsViewModel::class.java)
        // 觀察 LiveData 數(shù)據(jù)變化
        newsViewModel.newsList.observe(this, { news ->
            // 更新 UI
            news.forEach {
                textView.append("$it\n")
            }
        })
    }
}

當(dāng)屏幕旋轉(zhuǎn)等配置更改時,MainActivity 重新創(chuàng)建,但 NewsViewModel 實(shí)例會從 ViewModelStore 中取出,數(shù)據(jù)得以保留。 

LiveData 工作原理

  • 數(shù)據(jù)持有與觀察者管理LiveData 內(nèi)部維護(hù)著一個數(shù)據(jù)對象和一個觀察者列表。當(dāng)調(diào)用 observe 方法注冊觀察者時,會將 LifecycleOwner 和 Observer 包裝成 LifecycleBoundObserver 對象并添加到觀察者列表中。
  • 生命周期感知LifecycleBoundObserver 實(shí)現(xiàn)了 LifecycleEventObserver 接口,能夠監(jiān)聽 LifecycleOwner 的生命周期變化。當(dāng) LifecycleOwner 進(jìn)入活躍狀態(tài)(STARTED 或 RESUMED)時,LiveData 會將最新數(shù)據(jù)發(fā)送給該觀察者;當(dāng) LifecycleOwner 進(jìn)入銷毀狀態(tài)(DESTROYED)時,LiveData 會自動移除該觀察者,避免內(nèi)存泄漏。
  • 數(shù)據(jù)更新通知:當(dāng)調(diào)用 setValue(主線程)或 postValue(子線程)方法更新數(shù)據(jù)時,LiveData 會檢查所有觀察者的生命周期狀態(tài),只有處于活躍狀態(tài)的觀察者才會收到 onChanged 方法的調(diào)用,從而更新 UI。

 LiveData 持有數(shù)據(jù),通過 LifecycleBoundObserver 感知 LifecycleOwner 生命周期,僅在活躍狀態(tài)時通知觀察者。

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
    private val liveData = MutableLiveData<String>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView{"name":"GodelPlugin","parameters":{"input":"\"setContentView(R.layout.activity_main)\""}}<|FunctionExecuteEnd|><|FunctionExecuteResult|>setContentView(R.layout.activity_main)<|FunctionExecuteResultEnd|>
        // 注冊觀察者
        liveData.observe(this, Observer { data ->
            // 處理數(shù)據(jù)變化
            textView.text = data
        })
        // 更新數(shù)據(jù)
        liveData.value = "新數(shù)據(jù)"
    }
}

liveData.observe 注冊時將 this(即 MainActivity 作為 LifecycleOwner)和 Observer 包裝,當(dāng) MainActivity 處于活躍狀態(tài)且 liveData 數(shù)據(jù)更新時,Observer 的 onChanged 方法被調(diào)用。 

Room 工作原理

  • 抽象層封裝:Room 提供了一個抽象層,開發(fā)者通過定義實(shí)體類(使用 @Entity 注解)、數(shù)據(jù)訪問對象(DAO,使用 @Dao 注解)和數(shù)據(jù)庫類(使用 @Database 注解)來描述數(shù)據(jù)庫結(jié)構(gòu)和操作。實(shí)體類對應(yīng)數(shù)據(jù)庫表,DAO 定義了對數(shù)據(jù)庫的增刪改查操作,數(shù)據(jù)庫類則管理數(shù)據(jù)庫的版本和 DAO 實(shí)例。
  • 編譯時處理:在編譯時,Room 會根據(jù)開發(fā)者定義的注解生成相應(yīng)的 SQLite 語句和實(shí)現(xiàn)代碼。這樣可以在編譯階段就發(fā)現(xiàn)數(shù)據(jù)庫操作中的錯誤,提高開發(fā)效率和代碼的健壯性。
  • 線程管理:Room 默認(rèn)不允許在主線程中執(zhí)行數(shù)據(jù)庫操作,因?yàn)閿?shù)據(jù)庫操作通常是耗時的,可能會導(dǎo)致 UI 卡頓。因此,Room 會將數(shù)據(jù)庫操作放在后臺線程中執(zhí)行,開發(fā)者可以使用 suspend 函數(shù)(在 Kotlin 中)或自定義線程池來處理異步操作。

 Room 通過注解定義數(shù)據(jù)庫結(jié)構(gòu)和操作,編譯時生成 SQL 語句和實(shí)現(xiàn)代碼,默認(rèn)在后臺線程執(zhí)行操作。

// 定義實(shí)體類
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "news")
data class News(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val title: String
)
// 定義 DAO
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
@Dao
interface NewsDao {
    @Insert
    suspend fun insertNews(news: News)
    @Query("SELECT * FROM news")
    suspend fun getAllNews(): List<News>
}
// 定義數(shù)據(jù)庫類
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [News::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun newsDao(): NewsDao
}
// 在 ViewModel 中使用 Room
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class NewsViewModel : ViewModel() {
    private val database = Room.databaseBuilder(
        applicationContext,
        AppDatabase::class.java,
        "news-database"
    ).build()
    private val newsDao = database.newsDao()
    fun insertNews(news: News) {
        viewModelScope.launch {
            newsDao.insertNews(news)
        }
    }
    fun getAllNews() {
        viewModelScope.launch {
            val newsList = newsDao.getAllNews()
            // 處理獲取到的新聞列表
        }
    }
}

編譯時,Room 會根據(jù) @Entity、@Dao 和 @Database 注解生成操作數(shù)據(jù)庫的 SQL 語句和實(shí)現(xiàn)代碼,suspend 函數(shù)保證數(shù)據(jù)庫操作在后臺線程執(zhí)行。 

Navigation 工作原理

  • 導(dǎo)航圖定義:開發(fā)者通過 XML 文件定義導(dǎo)航圖,導(dǎo)航圖中包含了應(yīng)用的所有目的地(如 Fragment)、動作(用于在目的地之間導(dǎo)航)和參數(shù)傳遞規(guī)則。每個目的地都有唯一的標(biāo)識符,動作則定義了從一個目的地到另一個目的地的導(dǎo)航路徑。
  • 導(dǎo)航控制器管理NavController 是 Navigation 組件的核心,負(fù)責(zé)管理導(dǎo)航操作。它會根據(jù)導(dǎo)航圖中的定義,處理目的地之間的切換和參數(shù)傳遞。在 Activity 或 Fragment 中,可以通過 findNavController 方法獲取 NavController 實(shí)例,然后調(diào)用其 navigate 方法進(jìn)行導(dǎo)航。
  • Back Stack 管理NavController 維護(hù)了一個返回棧(Back Stack),用于記錄導(dǎo)航歷史。當(dāng)用戶點(diǎn)擊返回按鈕時,NavController 會從返回棧中彈出上一個目的地,實(shí)現(xiàn)返回操作。開發(fā)者可以通過配置導(dǎo)航圖中的 popUpTo 和 popUpToInclusive 屬性來控制返回棧的行為。

Navigation 通過導(dǎo)航圖定義目的地和動作,NavController 管理導(dǎo)航和返回棧。

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_graph"
    app:startDestination="@id/firstFragment">
    <fragment
        android:id="@+id/firstFragment"
        android:name="com.example.myapp.FirstFragment"
        android:label="First Fragment">
        <action
            android:id="@+id/action_firstFragment_to_secondFragment"
            app:destination="@id/secondFragment" />
    </fragment>
    <fragment
        android:id="@+id/secondFragment"
        android:name="com.example.myapp.SecondFragment"
        android:label="Second Fragment" />
</navigation>

在 Activity 中設(shè)置導(dǎo)航宿主

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true"
    app:navGraph="@navigation/navigation_graph" />

在 Fragment 中進(jìn)行導(dǎo)航

import androidx.fragment.app.Fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
class FirstFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_first, container, false)
        view.findViewById<Button>(R.id.navigateButton).setOnClickListener {
            // 導(dǎo)航到 SecondFragment
            findNavController().navigate(R.id.action_firstFragment_to_secondFragment)
        }
        return view
    }
}

 NavController 根據(jù)導(dǎo)航圖中的定義,處理從 FirstFragment 到 SecondFragment 的導(dǎo)航,同時管理返回棧以支持返回操作。

 總結(jié):

  ViewModel 通過 ViewModelStore 管理 UI 數(shù)據(jù)并在配置變更時保持狀態(tài),LiveData 實(shí)現(xiàn)生命周期感知的可觀察數(shù)據(jù)更新,Room 作為 SQLite ORM 自動生成數(shù)據(jù)庫操作代碼并處理線程,Navigation 利用導(dǎo)航圖和 NavController 管理多 Fragment 導(dǎo)航,共同構(gòu)建響應(yīng)式、可維護(hù)的 Android 應(yīng)用架構(gòu)。

到此這篇關(guān)于kotlin中的模塊化結(jié)構(gòu)組件的文章就介紹到這了,更多相關(guān)kotlin模塊化結(jié)構(gòu)組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論