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

开发测验App:能否将Activity存入array实现题目前后切换?

关于测验App题目切换方案的分析与优化建议

嘿,这个思路的出发点是好的——想让后续增删题目更便捷,但直接把Activity存入数组的方案并不推荐,甚至可以说在实际开发中会踩很多坑,咱们来拆解下:

为什么直接存Activity数组不可行?

  • 内存开销爆炸:每个Activity都是Android里的重量级组件,包含大量视图、上下文和生命周期逻辑。把它们提前存入数组意味着这些Activity会被提前实例化,占用大量内存,题目数量多的话很容易触发OOM(内存溢出),导致App崩溃。
  • 生命周期管理混乱:Android系统对Activity的生命周期有严格的管控逻辑,你手动把Activity存在数组里会打破这个规则——比如本该被系统销毁的Activity因为被数组持有而无法释放,造成内存泄漏;或者切换时出现页面数据错乱等状态异常。
  • 扩展性并没有真正提升:增删题目还是要单独编写新的Activity文件,本质上没有减少重复代码,反而多了维护数组的额外成本——比如要保证数组顺序和题目顺序完全对应,稍微疏忽就会出现题目跳转错误。

推荐的优化方案

方案1:单Activity + 多Fragment模式

只保留一个主Activity,每个题目对应一个轻量化的Fragment,把Fragment的Class(而非实例)存入数组。切换题目时通过FragmentManager替换当前Fragment即可:

// 存储Fragment的Class数组
val questionFragmentClasses = arrayOf(
    Question1Fragment::class.java,
    Question2Fragment::class.java,
    Question3Fragment::class.java
)

// 切换到下一题的示例代码
fun navigateToNextQuestion(currentIndex: Int) {
    if (currentIndex < questionFragmentClasses.size - 1) {
        val nextFragment = questionFragmentClasses[currentIndex + 1].newInstance()
        supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, nextFragment)
            .addToBackStack(null)
            .commit()
    }
}

这种方式的优势是内存占用小,Fragment的生命周期符合系统规范,增删题目时只需要新增/删除Fragment类,再调整数组即可。

方案2:数据驱动的单页面模式(最推荐)

这才是真正实现“低耦合、高扩展”的最优解:

  1. 把所有题目数据封装成一个数据类:
data class Question(
    val id: Int,
    val title: String,
    val options: List<String>,
    val correctAnswer: String,
    // 可根据需求添加更多字段,比如解析、图片资源ID等
)
  1. 把所有题目存入一个列表:
val questionList = listOf(
    Question(1, "1+1等于多少?", listOf("2", "3", "4"), "2"),
    Question(2, "Android四大组件不包括以下哪一个?", listOf("Activity", "Service", "Fragment", "BroadcastReceiver"), "Fragment")
)
  1. 只用一个布局页面,通过代码动态刷新UI内容:
// 刷新当前题目UI的方法
fun updateCurrentQuestion(index: Int) {
    val currentQuestion = questionList[index]
    // 更新题干文本
    tv_question_title.text = currentQuestion.title
    // 更新选项(比如清空RadioGroup后重新添加RadioButton)
    rg_options.removeAllViews()
    currentQuestion.options.forEach { option ->
        val radioButton = RadioButton(this)
        radioButton.text = option
        rg_options.addView(radioButton)
    }
}

切换题目时,只需要修改当前索引,调用updateCurrentQuestion方法即可。这种方式下,增删题目完全不需要修改UI代码,只需要调整questionList的数据即可,维护成本极低,性能也最优。

总结

你的原始方案理论上能运行,但在性能、可维护性上都是糟糕的选择。强烈推荐采用数据驱动的单页面模式,如果一定要为每个题目做单独的UI布局,再退一步选择单Activity+Fragment的方式,这两种都是Android开发中处理这类测验场景的常规做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:11:44