操作系统杀死/还原此活动后,如何还原从其他活动构造的对象

时间:2019-02-08 14:26:04

标签: android-activity kotlin onsaveinstancestate

activity 1中的module 1有两个模块,它们将根据用户操作将一些对象设置为运行上下文。它将从activity 2启动module 2。来自activity 2的{​​{1}}将使用更新的对象作为其处理的运行上下文。

问题是module 1(在资源紧张的情况下,即收到一个隐藏了应用程序的电话-操作系统杀死了进程-在电话操作系统还原应用程序后),操作系统将还原{{1} },但是上一活动正在运行的上下文设置已消失,如何恢复OS kills the process and restores

示例:

last activity

running context中,interface Handler { fun func_1(data: Data) fun func_2 (data: Data) } class Processor (val hanlder: Handler, var which: Int) { fun doProcess(data: Data) { when (which) { 1 -> { hanlder.func_1(data) } 2-> { hanlder.func_2(data) } } } } //using global (good or bad???) to avoid passing obj crossing activities object Running_context { lateinit var _processor: Processor fun setProcessor(processor: Processor) { this._processor = processor } fun getProcessor() :Processor { return this._processor } } 将根据用户的操作来设置运行上下文,例如:

module 1

,并在启动的activity_1(在模块2中)中,将根据fun launch_activity_2 (which: Int) { var processor = Processor (object: Handler { override fun func_1(data: String) { // do something based on some data get from use in this activity // e.g: if (checkBox_a.isChecked) {do something...} } override fun func_2 (data: String) { // do other things... } }, which) // set up running context Running_context.setProcessor(processor) // launching the activity_2 from module_2 // ... } 的设置执行此过程:

activity 2

在引用activity 1的全局实例时,避免在活动之间传递fun doProcess(data: String) { Running_context.getProcessor().doProcess(data) }

但是,即使在OS受限的情况下,它也可能会终止进程,然后将其还原,而在还原流程中,最后一个活动是object Running_context中的object/function point,并且全局实例没有正确的运行上下文最后一次。

  1. 将对象/功能点传递到另一个活动并在操作系统终止/恢复该活动时使它们恢复的最佳方法是什么?

  2. 另一个问题,如果活动2来自第三方库并且没有访问activity 2的权限,那么正在运行的上下文必须传递到{{ 1}}({{1}所依赖的module 2中定义了global object Running_contextactivity 2'?

2 个答案:

答案 0 :(得分:1)

您似乎已经意识到,即使将数据存储在全局单例中也无济于事,当应用被杀死并恢复时。我认为您可以做的最好的事情是在每个活动的生命周期中找到一个好位置(onPause和onResume很好),以进行序列化/反序列化并将数据保存/恢复到持久性存储中。

看看关于这个主题的guide。如果您没有庞大的复杂对象,我喜欢使用SharedPreferences

  

共享的首选项如果您不需要存储大量数据,   不需要结构,您应该使用SharedPreferences。的   使用SharedPreferences API,您可以读写持久性   原始数据类型的键/值对:布尔值,浮点数,整数,   长和字符串。

     

键值对被写入到XML文件中,该文件在用户之间持续存在   会话,即使您的应用被终止也是如此。您可以手动指定名称   文件或使用按活动记录文件保存数据。

     

API名称“共享的首选项”有点误导,因为该API   并非严格用于保存“用户偏好设置”,例如   用户已选择。您可以使用SharedPreferences保存任何类型的   简单数据,例如用户的高分。但是,如果您确实想   保存您的应用的用户偏好设置,那么您应该阅读如何创建   设置用户界面,该界面使用AndroidX首选项库构建   设置屏幕,并自动保留用户的设置。

答案 1 :(得分:1)

在@EpicPandaForce和@nPn的建议下,使用bundle传递上下文。

这是个主意,希望有人有更好的方法,谢谢!

module 2中,定义派生自的基本处理器类:

open class BaseProcessor() : Parcelable {

    open fun doProcess(data: Data){}

    // parceable stuff below
    /......
}

module 1中使用处理函数创建一个类

class TheHandler() {
   func_1 (data: Data) {
   }

   func_2 (data: Data) {
   }
}

制作从BaseProcessor派生的Processor(可能需要序列化一些原始数据,所以它很小)并覆盖doProcess(data: Data)
当调用TheHandler时,它将在运行时实例化doProcess(data: Data)类,并根据上下文值(即var which: Int)调用适当的函数

class Processor (var which: Int) : BaseProcessor {

    override fun doProcess(data: Data) {
        val handler = TheHandler()
        when (which) {
            1 -> {
                handler.func_1(data)
            }
            2-> {
                hanlder.func_2(data)
            }
        }
    }

    // parcelable stuff
    // ... ...
    override fun writeToParcel(out: Parcel, flags: Int) {
            super.writeToParcel(out, flags)
            out.writeInt(this.which)
    }

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<Processor> = object : Parcelable.Creator<Processor> {
            override fun createFromParcel(parcel: Parcel): Processor {
                return Processor(parcel)
            }

            override fun newArray(size: Int): Array<Processor?> {
                return arrayOfNulls(size)
            }
        }
    }
}

启动activity 2时,它将使用上下文数据构造Processor并将其放入新activity 2的分发包中

fun launch_activity_2 (which: Int) {
    var processor = Processor (which)

    // put processor in the bundle
    args.putParcelable(KEY_PROCESSOR_CONFIG, processor)

    // launching the activity_2 from module_2 with the bundle passed in 
    // ...
}

在模块2的活动2中,它期望从包中获取BaseProcessor并调用函数doProces() processor(它是Processor的实例)将具有上下文信息,并从TheHandler的{​​{1}中选择通过module 1类提供的适当功能。 }。

activity 1