V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
caobug
V2EX  ›  Android

请教 Android Activity 重建

  •  
  •   caobug · 2023-01-04 11:02:53 +08:00 · 8097 次点击
    这是一个创建于 680 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们的 APP 继承 Application 做了一些初始化操作,有些前台服务用不上的初始化搬到了 SplashActivity onCreate 中,为防止 SplashActivity 重建多次执行初始化,我在别的地方定义了一个静态变量标识。

    具体来说:

    Application onCreate 将初始化标记为 shouldBuild = true (默认 false )

    SplashActivity onCreate 判断 shouldBuild,并在事成后将 shouldBuild 标记为 false

    但 Picasso 仍抱怨 Singleton instance already exists.

      public static void setSingletonInstance(@NonNull Picasso picasso) {
        if (picasso == null) {
          throw new IllegalArgumentException("Picasso must not be null.");
        }
        synchronized (Picasso.class) {
          if (singleton != null) {
            throw new IllegalStateException("Singleton instance already exists.");
          }
          singleton = picasso;
        }
      }
    

    我从 Bugly 看到这些崩溃报告都是 APP 在后台时触发的,怀疑是 APP 被迫重建引起。

    但我感觉逻辑没问题呀,有大佬知道为什么么?

    9 条回复    2023-01-05 16:25:24 +08:00
    crayygy
        1
    crayygy  
       2023-01-04 11:18:47 +08:00
    信息不太全,从现有的信息里大概猜测可能跟静态变量有关系,也有可能是有多个 SplashActivity instance 同时起来了
    lisongeee
        2
    lisongeee  
       2023-01-04 11:24:13 +08:00
    我也不知道为什么

    但是你的 初始化标记 不能是 singleton==null 吗?
    AItsuki
        3
    AItsuki  
       2023-01-04 11:48:35 +08:00
    大概没做多进程重复初始化的判断?
    sth2018
        4
    sth2018  
       2023-01-04 12:00:09 +08:00
    if (intent.flags and Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT != 0) {
    finish()
    return
    }
    不知道这个能不能帮助到你这是资料链接 https://blog.csdn.net/sinat_31057219/article/details/104675649

    还有就是为什么要在 SplashActivity 进行初始化呢? SplashActivity 不是停留几秒就跳转到了首页吗?
    我平时习惯要么在 application 里初始化,实在想换地方会选择 MainActivity
    Guaidaodl
        5
    Guaidaodl  
       2023-01-04 12:17:46 +08:00
    听起来是多线程问题啊. 读写 shouldBuild 都在同一个线程吗?
    Guaidaodl
        6
    Guaidaodl  
       2023-01-04 12:21:08 +08:00
    如果想要防止 SplashActivity 重建导致初始化流程多次调用, 应该把 shouldBuild 变成 AtomicBoolean, 然后一开始就 compareSet(true, false).

    不应该是初始化才设置成 false. 不然你如果初始化还没有完成(如果你的初始化流程有线程切换)就又触发了 onCreate 就会运行两次.
    sparklee
        7
    sparklee  
       2023-01-04 17:01:41 +08:00
    全部放在 application 中初始化就好了
    acidsweet
        8
    acidsweet  
       2023-01-04 20:35:18 +08:00
    抛开 Activity 重建导致重走生命周期,单例的使用规范不应该作为类的成员变量存在
    caobug
        9
    caobug  
    OP
       2023-01-05 16:25:24 +08:00
    谢谢各位大佬,我找到原因了:

    冷启动 APP 会经过 SplashActivity 再跳转到 MainActivity 或其他界面。如果用户最后停留在 MainActivity ,当系统自动清理后台后 APP 可能会被迫重启,恢复后没走 SplashActivity 而是直接重建 MainActivity 。MainActivity 渲染图片时调用了 Picasso get 方法,它看到 singleton 为空就自动设置了 singleton 。当我返回桌面再次点开 APP 又走了一遍 SplashActivity 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1104 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 22:44 · PVG 06:44 · LAX 14:44 · JFK 17:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.