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

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

问题描述

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

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

当某个应用程序进入后台,并且在使用其他应用程序一段时间后,我尝试在Cache对象中打开应用程序变量为null时,发生了问题.当我终止该应用程序并再次打开它时,一切正常. 我正在使用依赖项注入来访问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?

这是我的Cache类

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

这是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并非如此,您很容易崩溃,因为在内存不足的情况发生之后,首先只会重新创建 current 活动,而在向后导航时会重新创建先前的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).

尝试一下:

  • 使用HOME按钮将应用程序置于后台

单击Android Studio中Logcat选项卡上的 TERMINATE按钮( 注意: ,Android Studio 4.x的行为会有所不同,并且您需要使用adb shell am kill <packagename>.)

click the TERMINATE button on Logcat tab in Android Studio (NOTE: Android Studio 4.x behaves differently, and you need to use adb shell am kill <packagename>.)

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

您将遇到这种现象.

在Android Studio 4.0中,终止"按钮会发出am force-stop,因此您需要使用am kill变体.

In Android Studio 4.0, the Terminate button issues am force-stop, and so you need to use am kill variant.

解决方案:检查是否为空,然后在基本活动(或LiveData.onActive)中重新初始化事物.

Solution: check for nulls and re-initialize things in a base activity (or in LiveData.onActive).

根据 https://codelabs.developers.google.com/codelabs/android-lifecycles/#6 ,您还可以使用以下终端命令触发Terminate Application按钮的行为:

As per https://codelabs.developers.google.com/codelabs/android-lifecycles/#6 , you can also trigger the Terminate Application button's behavior with the following terminal command:

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

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

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