应用程序恢复后单例对象变为空 [英] Singleton object becomes null after app is resumed

查看:24
本文介绍了应用程序恢复后单例对象变为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的 Android 项目,我需要全局单例 Cache 对象来通过应用程序访问有关用户的数据.

For my Android project, I need global singleton Cache object to access data about a user through the app.

当应用程序进入后台并且在使用其他应用程序一段时间后我尝试打开缓存对象中的应用程序变量时出现问题为空.当我杀死应用程序并再次打开它时,一切都很好.我正在使用依赖注入来访问 Cache 对象.如果发生这种情况,为什么应用程序不会再次启动?即使在内存不足的情况下,是否有一些注释可以保持缓存变量?

A problem occurs when an app goes into the background and after some time of using other apps I try to open app variables in Cache objects are null. Everything is okay when I kill the app and open it again. I'm using dependency injection to access Cache object. Why doesn't app start again if that happened? Is there some annotation to keep cache variable even in low memory conditions?

这是我的缓存类

class Cache {
    var categories : Array<BaseResponse.Category>? = null
    var user : BaseResponse.User? = null
    var options : BaseResponse.OptionsMap? = null
    var order: MenuOrderDataModel? = null
}

这是用于 DI 的存储模块

This is Storage module for DI

@Module class StorageModule {

    @Singleton @Provides fun getSharedPrefs(context: Context): SharedPreferences {
        return PreferenceManager.getDefaultSharedPreferences(context)
    }


    @Singleton @Provides fun getCache() : Cache = Cache()
}

我注入对象 @Inject lateinit var cache: Cache 然后在启动画面中填充用户数据.

I inject object @Inject lateinit var cache: Cache and then populate with user data in splash screen.

编辑 - 添加来自应用程序和启动活动的代码片段

Edit - added code snippets from Application and launch activity

class MyApp : Application() {
    val component: ApplicationComponent by lazy {
        DaggerApplicationComponent
                .builder()
                .appModule(AppModule(this))
                .build()
    }

    companion object {
        @JvmStatic lateinit var myapp: MyApp 
    }

    override fun onCreate() {
        super.onCreate()
        myapp= this
        Fabric.with(this, Crashlytics())
    }
}

飞溅活动:

class SplashActivity : AppCompatActivity(), View.OnClickListener {

    @Inject lateinit var viewModel : ISplashViewModel
    private lateinit var disposable : Disposable

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

        MyApp.myapp.component.inject(this)
}

推荐答案

您会崩溃,因为您在一个 Activity 中初始化这些变量,并期望它在另一个 Activity 中始终设置.

You're getting crashes because you initialize those variables in one Activity, and expect it to be set always, in the other Activity.

但 Android 不是这样工作的,你很容易崩溃,因为在内存不足的情况发生后,只有 当前 Activity 被重新创建,前一个 Activity 在返回导航时重新创建,并且所有静态变量都被清零(因为该过程在技术上重新启动).

But Android doesn't work like that, you can easily end up crashing because after low memory condition happens, only the current Activity gets recreated at first, previous Activity is recreated on back navigation, and all static variables are nulled out (because the process is technically restarted).

试试看:

  • 使用主页按钮将您的应用程序置于后台

点击 Logcat 标签上的 TERMINATE 按钮

click the TERMINATE button on Logcat tab

  • 然后从启动器重新启动应用.

您会体验到这种现象.

在 Android Studio 4.0 中,当您从 Android Studio 使用 Run 而不是从启动器启动应用程序后,Terminate 按钮的工作方式有时会有所不同,并且可能会强制停止您的应用程序使它在您尝试时忘记您的任务状态.在这种情况下,只需再试一次,从启动器启动应用程序.它会在您第二次尝试时起作用.

In Android Studio 4.0, after you use Run from Android Studio instead of starting the app from launcher, the Terminate button SOMETIMES works a bit differently and MIGHT force-stop your app making it forget your task state on your attempt. In that case, just try again, launching the app from launcher. It will work on your second try.

您还可以触发终止应用程序"终端的行为,根据 https://codelabs.developers.google.com/codelabs/android-lifecycles/#6,它看起来像这样:

You can also trigger the "Terminate Application" behavior from the terminal, as per https://codelabs.developers.google.com/codelabs/android-lifecycles/#6, it looks like this:

$ adb shell am kill your.app.package.name


解决方案:检查空值并重新初始化基本活动(或 LiveData.onActive)中的内容,或使用 onSaveInstanceState.

这篇关于应用程序恢复后单例对象变为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆