我们的 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 被迫重建引起。
但我感觉逻辑没问题呀,有大佬知道为什么么?
|  |      1crayygy      2023-01-04 11:18:47 +08:00 信息不太全,从现有的信息里大概猜测可能跟静态变量有关系,也有可能是有多个 SplashActivity instance 同时起来了 | 
|  |      2lisongeee      2023-01-04 11:24:13 +08:00 我也不知道为什么 但是你的 初始化标记 不能是 singleton==null 吗? | 
|  |      3AItsuki      2023-01-04 11:48:35 +08:00 大概没做多进程重复初始化的判断? | 
|  |      4sth2018      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 | 
|  |      5Guaidaodl      2023-01-04 12:17:46 +08:00 听起来是多线程问题啊. 读写 shouldBuild 都在同一个线程吗? | 
|  |      6Guaidaodl      2023-01-04 12:21:08 +08:00 如果想要防止 SplashActivity 重建导致初始化流程多次调用, 应该把 shouldBuild 变成 AtomicBoolean, 然后一开始就 compareSet(true, false). 不应该是初始化才设置成 false. 不然你如果初始化还没有完成(如果你的初始化流程有线程切换)就又触发了 onCreate 就会运行两次. | 
|      7sparklee      2023-01-04 17:01:41 +08:00 全部放在 application 中初始化就好了 | 
|  |      8acidsweet      2023-01-04 20:35:18 +08:00 抛开 Activity 重建导致重走生命周期,单例的使用规范不应该作为类的成员变量存在 | 
|      9caobug OP 谢谢各位大佬,我找到原因了: 冷启动 APP 会经过 SplashActivity 再跳转到 MainActivity 或其他界面。如果用户最后停留在 MainActivity ,当系统自动清理后台后 APP 可能会被迫重启,恢复后没走 SplashActivity 而是直接重建 MainActivity 。MainActivity 渲染图片时调用了 Picasso get 方法,它看到 singleton 为空就自动设置了 singleton 。当我返回桌面再次点开 APP 又走了一遍 SplashActivity 。 |