博客
关于我
如何用更好的方式在 Activity 或 Fragment 之间传递以及返回数据?
阅读量:122 次
发布时间:2019-02-27

本文共 4203 字,大约阅读时间需要 14 分钟。

Activity Result 新方式:简化数据传递与调试

在Android开发中,Activity之间传递数据通常涉及繁琐的逻辑和调试困难。传统的做法是通过定义不同RequestCode来实现数据的匹配,但这种方式在维护和调试时显然不够高效。最近,通过引入ActivityResultContract的方式,可以更简洁地实现数据传递,同时提升调试效率。本文将详细介绍这种新方式的优势,并对比传统实现,帮助开发者做出更优的选择。

传统实现的局限性

传统的Activity间数据传递主要依赖RequestCode进行匹配:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_PERMISSION -> { // 处理成功或失败情况
}
REQUEST_MULTIPLE_PERMISSION -> { // 处理成功或失败情况
}
REQUEST_TO_POST -> { // 解析结果并执行操作
}
}
}
super.onActivityResult(requestCode, resultCode, data)
}

这种方式需要开发者手动定义多个RequestCode,并在每个ActivityResult中进行分类处理。虽然灵活,但随着项目复杂度增加,维护成本上升。此外,调试时需要逐一分析不同RequestCode对应的数据,工作量显然较大。

Activity Result 新方式:更高效的数据传递方案

通过引入ActivityResultContract,可以在Activity间实现更加简洁和高效的数据传递。这种方式结合了Android的生命周期管理,使得数据传递更加自动化和安全。

实现步骤

  • 加入依赖

    首先需要引入相关的库:

    implementation 'androidx.activity:activity-ktx:1.2.0-alpha08'
    implementation 'androidx.fragment:fragment-ktx:1.3.0-alpha08'
  • 编码

    接下来,开发者需要创建ActivityResultContract的实现类。例如,定义一个PostActivityContract,传递所需的数据:

    class PostActivityContract(private val postId: Int) : ActivityResultContract
    {
    override fun createIntent(context: Context, input: Int): Intent {
    return Intent(context, ResultActivity::class.java).apply {
    putExtra(MainActivity.ID, postId)
    }
    }
    override fun parseResult(resultCode: Int, intent: Intent?): String? {
    val data = intent?.getStringExtra(ResultActivity.TITLE)
    return if (resultCode == Activity.RESULT_OK && data != null) {
    data
    } else {
    null
    }
    }
    }

    这个Contract类继承自ActivityResultContract,并覆盖了createIntent和parseResult两个方法。createIntent用于创建启动ResultActivity的Intent,parseResult用于解析返回的数据。

  • 使用方式

    在主Activity中注册ActivityResultContract,并调用launch方法:

    class MainActivity : AppCompatActivity() {
    private val openPostActivityCustom =
    registerForActivityResult(PostActivityContract(2)) { result ->
    Log.d("MainActivity", "Result: $result")
    }
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    openPostActivityCustom.launch(1)
    }
    companion object {
    val ID = "id"
    }
    }

    调用registerForActivityResult方法注册回调,传递所需的参数。然后在需要启动ResultActivity的位置调用launch方法。

  • ResultActivity的处理

    ResultActivity在接收数据后,通过setResult方法将结果返回:

    class ResultActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_result)
    Log.d("ResultActivity", intent.getIntExtra(MainActivity.ID, 0).toString())
    }
    companion object {
    val TITLE = "title"
    }
    fun result(view: View) {
    setResult(Activity.RESULT_OK, Intent().apply {
    putExtra(TITLE, "title")
    })
    finish()
    }
    }

    这里,ResultActivity通过setResult方法将处理结果返回给调用方,并通过log记录处理后的数据。

  • 优势对比

    优势一:简化参数传递

    通过ActivityResultContract的方式,开发者只需传递参数而不需要关心其key的定义。例如,在调用launch方法时,只需传递所需的参数ID,而不需要手动定义key。这种方式极大地降低了参数传递的复杂度,尤其是在多次传递数据时,减少了key的重构风险。

    优势二:无需定义RequestCode

    传统方式需要手动定义多个RequestCode,并根据requestCode进行分类处理。而新方式通过ActivityResultContract自动管理RequestCode,开发者不需要关心具体的requestCode值,系统会自动处理相关生命周期。这种方式减少了代码的复杂度,也提升了代码的可维护性。

    优势三:结合生命周期管理

    ActivityResultContract的实现方式结合了Android的生命周期管理。在Activity销毁时,系统会自动清除相关的RequestCode和回调,避免了内存泄漏和回调错误。这种方式对于多个Fragment或组件之间的数据传递尤为重要。

    Fragment Result 新方式

    除了Activity之间的数据传递,Fragment之间的数据传递也有类似的优化方式。通过FragmentResultListener,可以在Fragment间实现更加灵活和安全的数据传递。

    代码示例

    在FragmentB中设置结果:

    button.setOnClickListener {
    val result = "result"
    // 使用Kotlin扩展方法
    setResult("requestKey", bundleOf("bundleKey" to result))
    }

    在FragmentA中注册回调:

    FragmentManager.setFragmentResultListener(
    "requestKey",
    lifecycleOwner,
    FragmentResultListener { _, bundle ->
    // 处理结果
    }
    )

    这种方式需要确保在Fragment之间使用相同的requestKey,以保证数据传递的准确性。同时,Fragment的生命周期管理会自动取消不需要的回调,避免内存泄漏。

    总结

    通过引入ActivityResultContract和FragmentResultListener,开发者可以在Activity和Fragment间实现更加简洁和高效的数据传递。这种方式不仅降低了代码复杂度,还提升了调试效率和维护能力。对于需要多次传递数据的场景,这种方式无疑是一个更优的选择。

    转载地址:http://lezb.baihongyu.com/

    你可能感兴趣的文章
    LiveGBS user/save 逻辑缺陷漏洞复现(CNVD-2023-72138)
    查看>>
    localhost:5000在MacOS V12(蒙特利)中不可用
    查看>>
    logstash mysql 准实时同步到 elasticsearch
    查看>>
    Luogu2973:[USACO10HOL]赶小猪
    查看>>
    mabatis 中出现< 以及> 代表什么意思?
    查看>>
    Mac book pro打开docker出现The data couldn’t be read because it is missing
    查看>>
    MAC M1大数据0-1成神篇-25 hadoop高可用搭建
    查看>>
    mac mysql 进程_Mac平台下启动MySQL到完全终止MySQL----终端八步走
    查看>>
    Mac OS 12.0.1 如何安装柯美287打印机驱动,刷卡打印
    查看>>
    MangoDB4.0版本的安装与配置
    查看>>
    Manjaro 24.1 “Xahea” 发布!具有 KDE Plasma 6.1.5、GNOME 46 和最新的内核增强功能
    查看>>
    mapping文件目录生成修改
    查看>>
    MapReduce程序依赖的jar包
    查看>>
    mariadb multi-source replication(mariadb多主复制)
    查看>>
    MariaDB的简单使用
    查看>>
    MaterialForm对tab页进行隐藏
    查看>>
    Member var and Static var.
    查看>>
    memcached高速缓存学习笔记001---memcached介绍和安装以及基本使用
    查看>>
    memcached高速缓存学习笔记003---利用JAVA程序操作memcached crud操作
    查看>>
    Memcached:Node.js 高性能缓存解决方案
    查看>>