当前位置: 代码网 > it编程>编程语言>Java > kotlin中的模块化结构组件及工作原理

kotlin中的模块化结构组件及工作原理

2025年03月15日 Java 我要评论
模块化结构组件包含viewmodel、livedata、room 和 navigation ,我将讲解它们的工作原理和基础使用。viewmodel 工作原理创建与存储机制:当调用viewmodelpr

模块化结构组件包含viewmodel、livedata、room 和 navigation ,我将讲解它们的工作原理和基础使用。

viewmodel 工作原理

  • 创建与存储机制:当调用 viewmodelprovider 的 get 方法获取 viewmodel 实例时,viewmodelprovider 会先检查 viewmodelstore 中是否已存在该类型的实例。若存在则直接返回,若不存在则使用 viewmodelprovider.factory 创建新实例并存储在 viewmodelstore 中。每个 activity 和 fragment 都有各自对应的 viewmodelstore,用于管理其内部的 viewmodel 实例。
  • 生命周期管理viewmodel 的生命周期与关联的 activity 或 fragment 紧密相关,但又有区别。在配置更改(如屏幕旋转)时,activity 或 fragment 会重新创建,而 viewmodelstore 会被保留,所以 viewmodel 实例也得以保留,从而保证数据的一致性。当 activity 或 fragment 被销毁(非因配置更改)时,viewmodelstore 会调用 clear 方法,进而调用 viewmodel 的 oncleared 方法,让开发者可以在此进行资源释放操作。

viewmodel 通过 viewmodelstore 存储实例,在配置更改时保留数据,在关联组件非配置更改销毁时释放资源。 

// 定义 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 {
        // 模拟从网络或数据库获取新闻数据
        fetchnews()
    }
    private fun fetchnews() {
        // 这里可以替换为真实的网络请求或数据库查询
        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 实例
        newsviewmodel = viewmodelprovider(this).get(newsviewmodel::class.java)
        // 观察 livedata 数据变化
        newsviewmodel.newslist.observe(this, { news ->
            // 更新 ui
            news.foreach {
                textview.append("$it\n")
            }
        })
    }
}

当屏幕旋转等配置更改时,mainactivity 重新创建,但 newsviewmodel 实例会从 viewmodelstore 中取出,数据得以保留。 

livedata 工作原理

  • 数据持有与观察者管理livedata 内部维护着一个数据对象和一个观察者列表。当调用 observe 方法注册观察者时,会将 lifecycleowner 和 observer 包装成 lifecycleboundobserver 对象并添加到观察者列表中。
  • 生命周期感知lifecycleboundobserver 实现了 lifecycleeventobserver 接口,能够监听 lifecycleowner 的生命周期变化。当 lifecycleowner 进入活跃状态(started 或 resumed)时,livedata 会将最新数据发送给该观察者;当 lifecycleowner 进入销毁状态(destroyed)时,livedata 会自动移除该观察者,避免内存泄漏。
  • 数据更新通知:当调用 setvalue(主线程)或 postvalue(子线程)方法更新数据时,livedata 会检查所有观察者的生命周期状态,只有处于活跃状态的观察者才会收到 onchanged 方法的调用,从而更新 ui。

 livedata 持有数据,通过 lifecycleboundobserver 感知 lifecycleowner 生命周期,仅在活跃状态时通知观察者。

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 ->
            // 处理数据变化
            textview.text = data
        })
        // 更新数据
        livedata.value = "新数据"
    }
}

livedata.observe 注册时将 this(即 mainactivity 作为 lifecycleowner)和 observer 包装,当 mainactivity 处于活跃状态且 livedata 数据更新时,observer 的 onchanged 方法被调用。 

room 工作原理

  • 抽象层封装:room 提供了一个抽象层,开发者通过定义实体类(使用 @entity 注解)、数据访问对象(dao,使用 @dao 注解)和数据库类(使用 @database 注解)来描述数据库结构和操作。实体类对应数据库表,dao 定义了对数据库的增删改查操作,数据库类则管理数据库的版本和 dao 实例。
  • 编译时处理:在编译时,room 会根据开发者定义的注解生成相应的 sqlite 语句和实现代码。这样可以在编译阶段就发现数据库操作中的错误,提高开发效率和代码的健壮性。
  • 线程管理:room 默认不允许在主线程中执行数据库操作,因为数据库操作通常是耗时的,可能会导致 ui 卡顿。因此,room 会将数据库操作放在后台线程中执行,开发者可以使用 suspend 函数(在 kotlin 中)或自定义线程池来处理异步操作。

 room 通过注解定义数据库结构和操作,编译时生成 sql 语句和实现代码,默认在后台线程执行操作。

// 定义实体类
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>
}
// 定义数据库类
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 会根据 @entity@dao 和 @database 注解生成操作数据库的 sql 语句和实现代码,suspend 函数保证数据库操作在后台线程执行。 

navigation 工作原理

  • 导航图定义:开发者通过 xml 文件定义导航图,导航图中包含了应用的所有目的地(如 fragment)、动作(用于在目的地之间导航)和参数传递规则。每个目的地都有唯一的标识符,动作则定义了从一个目的地到另一个目的地的导航路径。
  • 导航控制器管理navcontroller 是 navigation 组件的核心,负责管理导航操作。它会根据导航图中的定义,处理目的地之间的切换和参数传递。在 activity 或 fragment 中,可以通过 findnavcontroller 方法获取 navcontroller 实例,然后调用其 navigate 方法进行导航。
  • back stack 管理navcontroller 维护了一个返回栈(back stack),用于记录导航历史。当用户点击返回按钮时,navcontroller 会从返回栈中弹出上一个目的地,实现返回操作。开发者可以通过配置导航图中的 popupto 和 popuptoinclusive 属性来控制返回栈的行为。

navigation 通过导航图定义目的地和动作,navcontroller 管理导航和返回栈。

<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 中设置导航宿主

<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 中进行导航

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 {
            // 导航到 secondfragment
            findnavcontroller().navigate(r.id.action_firstfragment_to_secondfragment)
        }
        return view
    }
}

 navcontroller 根据导航图中的定义,处理从 firstfragment 到 secondfragment 的导航,同时管理返回栈以支持返回操作。

 总结:

  viewmodel 通过 viewmodelstore 管理 ui 数据并在配置变更时保持状态,livedata 实现生命周期感知的可观察数据更新,room 作为 sqlite orm 自动生成数据库操作代码并处理线程,navigation 利用导航图和 navcontroller 管理多 fragment 导航,共同构建响应式、可维护的 android 应用架构。

到此这篇关于kotlin中的模块化结构组件的文章就介绍到这了,更多相关kotlin模块化结构组件内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com