Как восстановить объекты, построенные из других действий после того, как ОС убивает / восстанавливает это действие - PullRequest
0 голосов
/ 08 февраля 2019

Имея два модуля, activity 1 из module 1 настроит некоторые объекты в качестве рабочего контекста на основе действий пользователя.И он запустит activity 2 с module 2activity 2 из module 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 настроит рабочий контекст на основе действий пользователя, таких как:

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 (вмодуль 2) будет выполнять процесс на основе установки с помощью activity 1:

fun doProcess(data: String) {
    Running_context.getProcessor().doProcess(data)
}

При обращении к глобальному экземпляру object Running_context он избегает пропускания object/function point между действиями.

Но все же, когда ОС находится под ограничениями, она может завершить процесс, а затем восстановить его, и в потоке восстановления последнее действие - activity 2 из module 2, а глобальный экземпляр не имеет корректного контекста выполнения в прошлый раз.

  1. Каков наилучший способ передать объектную / функциональную точку другому действию и восстановить их, когда os убивает / восстанавливает это действие?

  2. Другой вопросчто, если действие 2 происходит из сторонней библиотеки и не имеет доступа к global object Running_context, поэтому рабочий контекст должен быть передан в новый экземпляр activity 2'? (interface Handler и class Processorопределены в module 2, от которого зависит module 1

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

С предложением @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) {
   }
}

, что делает Processor производным от BaseProcessor (может иметьнесколько примитивных данных, которые нужно сериализовать, чтобы они были маленькими) и переопределить 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 птом module 1 х activity 1.

fun doProcess(data: String) {
    //somethinglike:

    val processor: BaseProcessor? = arguments?.getParcelable(KEY_PROCESSOR_CONFIG)
    processor?.doProcess(data)
}
0 голосов
/ 09 февраля 2019

Как вы понимаете, даже хранение данных в глобальном синглтоне не помогает, когда приложение убито и восстановлено.Я думаю, что лучшее, что вы можете сделать, - это найти хорошее место в жизненном цикле каждого действия (onPause и onResume - это хорошо) для сериализации / де-дериализации и сохранения / восстановления данных в постоянном хранилище.

Возьмитепосмотрите на руководство по этому вопросу.Если у вас нет огромного сложного объекта, я бы хотел использовать SharedPreferences .

Общие настройки Если вам не нужно хранить много данных, и это не такне требует структуры, вы должны использовать SharedPreferences.API-интерфейсы SharedPreferences позволяют считывать и записывать постоянные пары ключ-значение примитивных типов данных: логические значения, числа с плавающей запятой, целые числа, длинные значения и строки.

Пары ключ-значение записываются в файлы XML, которые сохраняются во всех пользователях.сессий, даже если ваше приложение убито.Вы можете вручную указать имя файла или использовать отдельные файлы для сохранения ваших данных.

Имя API «общие настройки» немного вводит в заблуждение, поскольку API не предназначен исключительно для сохранения «пользовательских настроек».например, какую мелодию звонка выбрал пользователь.Вы можете использовать SharedPreferences для сохранения любых простых данных, таких как высокий балл пользователя.Однако если вы хотите сохранить пользовательские настройки для своего приложения, вам следует прочитать, как создать пользовательский интерфейс настроек, который использует библиотеку предпочтений AndroidX для создания экрана настроек и автоматического сохранения настроек пользователя.

...