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