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

为何调用onDestroy后未创建新的Activity实例?

问题:为何Activity调用onDestroy后重启实例哈希值相同?

我编写了一个仅用于记录生命周期的简单Activity,代码如下:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("hello", "onCreate")
        Log.d("hello", this.toString())
    }
    override fun onStart(){
        super.onStart()
        Log.d("hello", "onStart")
    }
    override fun onResume(){
        super.onResume()
        Log.d("hello", "onResume")
    }
    override fun onPause(){
        super.onPause()
        Log.d("hello", "onPause")
    }
    override fun onStop(){
        super.onStop()
        Log.d("hello", "onStop")
    }
    override fun onDestroy(){
        super.onDestroy()
        Log.d("hello", "onDestroy")
    }
}

我在API 30的设备上运行该应用,按下概览键并上滑应用以杀死进程,Logcat显示如下内容:

---------------------------- PROCESS STARTED (10930) for package com.example.viewmodel ----------------------------
2023-12-13 14:32:06.935 10930-10930 hello                   com.example.viewmodel                D  onCreate
2023-12-13 14:32:06.935 10930-10930 hello                   com.example.viewmodel                D  com.example.viewmodel.MainActivity@2edf7d9
2023-12-13 14:32:07.010 10930-10930 hello                   com.example.viewmodel                D  onStart
2023-12-13 14:32:07.084 10930-10930 hello                   com.example.viewmodel                D  onResume
2023-12-13 14:32:10.573 10930-10930 hello                   com.example.viewmodel                D  onPause
2023-12-13 14:32:10.994 10930-10930 hello                   com.example.viewmodel                D  onStop
2023-12-13 14:32:11.634 10930-10930 hello                   com.example.viewmodel                D  onDestroy
---------------------------- PROCESS ENDED (10930) for package com.example.viewmodel ----------------------------

可以看到onDestroy方法已被调用,意味着Activity实例已被销毁。随后我从启动器重新启动应用,预期会看到Log.d("hello", this.toString())输出不同的值,但结果却完全相同:

---------------------------- PROCESS STARTED (10983) for package com.example.viewmodel ----------------------------
2023-12-13 14:41:01.475 10983-10983 hello                   com.example.viewmodel                D  onCreate
2023-12-13 14:41:01.475 10983-10983 hello                   com.example.viewmodel                D  com.example.viewmodel.MainActivity@2edf7d9
2023-12-13 14:41:01.541 10983-10983 hello                   com.example.viewmodel                D  onStart
2023-12-13 14:41:01.604 10983-10983 hello                   com.example.viewmodel                D  onResume

请问为何调用onDestroy后未创建新的Activity实例?


解答

这并不是没有创建新的Activity实例,问题出在对象toString()输出的哈希值并非唯一标识实例的可靠依据:

  • 默认情况下,Kotlin/Java中对象的toString()格式是类名@十六进制哈希码,这个哈希码来自Object类的hashCode()方法。在Android的ART虚拟机中,当进程重启后,内存地址空间会被重新分配,但出于内存优化或地址复用的机制,新创建的对象完全有可能复用之前实例的内存地址,导致哈希码看起来和旧实例一致。
  • 你看到的两次进程ID分别是10930和10983,这已经明确说明是两个完全独立的进程——不同进程的内存空间完全隔离,旧实例不可能跨进程存活,进程内的Activity必然是全新的实例。

如果要验证确实是新实例,可以添加一个实例级的随机变量来区分:

class MainActivity : AppCompatActivity() {
    private val instanceId = Random.nextInt() // 每个实例创建时生成唯一随机数

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("hello", "onCreate, instanceId: $instanceId")
        Log.d("hello", this.toString())
    }

    // 其余生命周期方法保持不变
}

重启应用后,你会看到每次的instanceId都不同,这就能证明确实创建了新的Activity实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 10:57:44