You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android多Activity间Workout与Exercise对象数组传递方案咨询

解决Android Activity间传递Workout/Exercise对象+单例初始化的最佳方案

嘿,针对你这个健身App的场景,我整理了两种最实用的方案,既能高效传递对象,又能保证Workout数组只初始化一次,咱们一起来看:

方案一:Parcelable + 单例管理器(传统Android项目首选)

Android里传递自定义对象最常用的就是Parcelable(比Serializable高效很多),搭配单例类来管理Workout数组,确保只初始化一次。

步骤拆解:

  1. 让Exercise和Workout实现Parcelable接口
    Android Studio可以帮你自动生成Parcelable代码:右键类名 → Generate → Parcelable,一键搞定。举个简单的Exercise类示例:

    class Exercise() : Parcelable {
        var name: String = ""
        var duration: Int = 0 // 秒
    
        constructor(parcel: Parcel) : this() {
            name = parcel.readString() ?: ""
            duration = parcel.readInt()
        }
    
        override fun writeToParcel(parcel: Parcel, flags: Int) {
            parcel.writeString(name)
            parcel.writeInt(duration)
        }
    
        override fun describeContents(): Int {
            return 0
        }
    
        companion object CREATOR : Parcelable.Creator<Exercise> {
            override fun createFromParcel(parcel: Parcel): Exercise {
                return Exercise(parcel)
            }
    
            override fun newArray(size: Int): Array<Exercise?> {
                return arrayOfNulls(size)
            }
        }
    }
    
  2. 创建单例WorkoutManager管理数组
    用单例来封装Workout数组的初始化和获取逻辑,保证全局只初始化一次:

    class WorkoutManager private constructor() {
        val workoutList: List<Exercise>
    
        init {
            // 这里只初始化一次,比如从本地资源/网络加载练习数据
            workoutList = listOf(
                Exercise("俯卧撑", 30),
                Exercise("深蹲", 45),
                Exercise("平板支撑", 60)
            )
        }
    
        companion object {
            @Volatile
            private var instance: WorkoutManager? = null
    
            fun getInstance(): WorkoutManager {
                return instance ?: synchronized(this) {
                    instance ?: WorkoutManager().also { instance = it }
                }
            }
        }
    
        // 辅助方法:根据索引获取对应练习
        fun getExerciseAt(index: Int): Exercise? {
            return if (index in workoutList.indices) workoutList[index] else null
        }
    }
    
  3. Activity间传递与数据获取

    • MainActivity点击start按钮时,传递第一个练习的索引到StartExercise:
      startBtn.setOnClickListener {
          val intent = Intent(this, StartExerciseActivity::class.java)
          intent.putExtra("CURRENT_INDEX", 0)
          startActivity(intent)
      }
      
    • StartExercise中获取当前练习:
      val currentIndex = intent.getIntExtra("CURRENT_INDEX", 0)
      val currentExercise = WorkoutManager.getInstance().getExerciseAt(currentIndex)
      // 展示练习内容...
      
      // 完成练习后启动RestActivity,传递下一个索引
      finishExerciseBtn.setOnClickListener {
          val nextIndex = currentIndex + 1
          val intent = Intent(this, RestActivity::class.java)
          intent.putExtra("NEXT_INDEX", nextIndex)
          startActivity(intent)
      }
      
    • RestActivity倒计时结束后,返回StartExercise并传递下一个索引:
      // 倒计时结束后
      val nextIndex = intent.getIntExtra("NEXT_INDEX", 0)
      val intent = Intent(this, StartExerciseActivity::class.java)
      intent.putExtra("CURRENT_INDEX", nextIndex)
      startActivity(intent)
      finish()
      

方案二:Jetpack ViewModel(现代Android项目推荐)

如果你的项目已经在用Jetpack组件,ViewModel绝对是更优解——它能在配置变化(比如旋转屏幕)时保留数据,还能让多个Activity共享同一个数据实例,完全不用手动传递对象。

步骤拆解:

  1. 添加ViewModel依赖
    在app模块的build.gradle里添加依赖(版本可以根据你的项目调整):

    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
    
  2. 创建共享的WorkoutViewModel
    ViewModel里初始化Workout数组,并管理当前练习的索引:

    class WorkoutViewModel : ViewModel() {
        val workoutList: List<Exercise> = listOf(
            Exercise("俯卧撑", 30),
            Exercise("深蹲", 45),
            Exercise("平板支撑", 60)
        )
        var currentExerciseIndex = 0
    
        // 获取当前练习
        fun getCurrentExercise(): Exercise? {
            return if (currentExerciseIndex in workoutList.indices) workoutList[currentExerciseIndex] else null
        }
    
        // 切换到下一个练习
        fun nextExercise() {
            if (currentExerciseIndex < workoutList.size - 1) {
                currentExerciseIndex++
            }
        }
    }
    
  3. 在各个Activity中使用ViewModel

    • MainActivity点击start按钮,直接跳转StartExercise即可,不用传递任何数据:
      startBtn.setOnClickListener {
          startActivity(Intent(this, StartExerciseActivity::class.java))
      }
      
    • StartExercise中获取ViewModel并展示当前练习:
      val viewModel = ViewModelProvider(this)[WorkoutViewModel::class.java]
      val currentExercise = viewModel.getCurrentExercise()
      // 展示练习内容...
      
      // 完成练习后启动RestActivity
      finishExerciseBtn.setOnClickListener {
          viewModel.nextExercise()
          startActivity(Intent(this, RestActivity::class.java))
      }
      
    • RestActivity倒计时结束后,直接finish返回StartExercise,StartExercise会自动从ViewModel拿到下一个练习:
      // 倒计时结束后
      finish()
      

方案对比

方案优点缺点
Parcelable+单例兼容性好,适合所有Android项目单例若持有不当可能引发内存泄漏(需用Application Context)
Jetpack ViewModel自动处理配置变化,无需手动传递数据,代码更简洁需要依赖Jetpack组件,适合现代项目

内容的提问来源于stack exchange,提问作者PeteF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:32:34