android: что нужно для восстановления статуса активности после обратной навигации? - PullRequest
0 голосов
/ 27 февраля 2019

Отказ от ответственности: я опытный программист, но почти полный новичок в Android;Я мог бы спросить об очевидном.

У меня довольно простой графический интерфейс для моего предварительного приложения.

В частности, у меня есть самый верхний Switch для включения / выключения моего приложения.

При запуске переключатель выключен.

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

MonitorActivity правильно связан с родителем, поэтому я могу вернуться к MainActivity.

Пока все хорошо.Все работает.

Проблема в том, что при обратной навигации MainActivity полностью сбрасывается, как будто началось заново;в частности, мое включение / выключение Switch вернулось в положение off.

Мое понимание соответствующей документации означает MainActivity, должно быть остановлено;Соответствующий фрагмент:

Предыдущее действие остается в стеке, но останавливается.Когда действие останавливается, система сохраняет текущее состояние своего пользовательского интерфейса.Когда пользователь нажимает кнопку «Назад», текущее действие извлекается из верхней части стека (действие уничтожается) и возобновляется предыдущее действие (восстанавливается предыдущее состояние его пользовательского интерфейса).

Исходя из этого, я понимаю, что не следует делать ничего конкретного для восстановления статуса MainActivity;это правильно?

Должен ли я публиковать свои AndroidMainfest.xml (или другие файлы)?

ОБНОВЛЕНИЕ (согласно запросу):

Я следуюстрого по шаблону MyFirstApp :

  • Запуск MonitorActivity с MainActivity с использованием startActivity(intent).
  • Back-naviagtion с использованием левой стрелки в главном меню(используя: <activity android:name=".DisplayMessageActivity" android:parentActivityName=".MainActivity"> in AndroidManifest.xml)

ПРИМЕЧАНИЕ : Это точно поведение MyFirstApp: при возврате из DisplayMessageActivity содержимое EditText виджет пропал (даже если никто явно не очищает его).

Возможно, мне следует переименовать вопрос: "Как я могу сохранить 'message' после 'Send' в 'MyFirstApp'?"

UPDATE2 : я переопределил несколько обратных вызовов для отслеживания того, что действительно происходит;вот журнал (комментарии встроены, ищите «<<<<<»): </p>

02/27 16:05:24: Launching app
$ adb install-multiple -r -t -p it.condarelli.myfirstapp /home/mcon/AndroidStudioProjects/MyfirstApp/app/build/intermediates/split-apk/debug/slices/slice_2.apk 
Split APKs installed in 483 ms
$ adb shell am start -n "it.condarelli.myfirstapp/it.condarelli.myfirstapp.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Waiting for application to come online: it.condarelli.myfirstapp | it.condarelli.myfirstapp.test
Waiting for application to come online: it.condarelli.myfirstapp | it.condarelli.myfirstapp.test
Connecting to it.condarelli.myfirstapp
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/elli.myfirstap: Not late-enabling -Xcheck:jni (already on)
W/elli.myfirstap: Unexpected CPU variant for X86 using defaults: x86
W/ActivityThread: Application it.condarelli.myfirstapp is waiting for the debugger on port 8100...
I/System.out: Sending WAIT chunk
I/System.out: Debugger has connected
    waiting for debugger to settle...
Connected to the target VM, address: 'localhost:8603', transport: 'socket'
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/chatty: uid=10085(it.condarelli.myfirstapp) identical 2 lines
I/System.out: waiting for debugger to settle...
I/System.out: debugger has settled (1354)
W/elli.myfirstap: JIT profile information will not be recorded: profile file does not exits.
I/chatty: uid=10085(it.condarelli.myfirstapp) identical 10 lines
W/elli.myfirstap: JIT profile information will not be recorded: profile file does not exits.
I/InstantRun: starting instant run server: is main process
I/MainActivity: onCreate(null)             <<<<< This is App start
W/elli.myfirstap: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
    Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
I/MainActivity: onStart()
I/MainActivity: onResume()
I/MainActivity: onPostResume()
D/OpenGLRenderer: HWUI GL Pipeline
D/: HostConnection::get() New Host Connection established 0xcb81c0c0, tid 17161
I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
    android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
D/OpenGLRenderer: Swap behavior 0
D/EGL_emulation: eglCreateContext: 0xde3584a0: maj 2 min 0 rcv 2
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
I/AssistStructure: Flattened final assist data: 2344 bytes, containing 1 windows, 8 views
I/MainActivity: onPause()                  <<<<< This is first message after I pressed 'Send' button.
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@18e99e1
I/DisplayMessageActivity: onStart()
I/DisplayMessageActivity: onResume()
I/DisplayMessageActivity: onPostResume()
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
I/MainActivity: onStop()
I/MainActivity: onSaveInstanceState()      <<<<< This is where log stops while DisplayMessageActivity is focused
I/DisplayMessageActivity: onPause()        <<<<< This is first message after Back-navigation
I/MainActivity: onDestroy()                <<<<< WHY THIS NOW??
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@bd33145
I/MainActivity: onCreate(null)             <<<<< MainActivity is recreated from scratch
I/MainActivity: onStart()
I/MainActivity: onResume()
I/MainActivity: onPostResume()
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
D/EGL_emulation: eglMakeCurrent: 0xde3584a0: ver 2 0 (tinfo 0xcb943060)
I/DisplayMessageActivity: onStop()
I/DisplayMessageActivity: onDestroy()

Что я делаю не так?

Ответы [ 3 ]

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

Оказывается, "виновником" является использование android.support.v7.app.AppCompatActivity, которое кажется (после большой отладки) для безоговорочного вызова requestDestroy() в конце dispatchMessage(), вызываемого в конце цепочкиинициируется startActivity(intent).

Реализация по умолчанию onSaveInstanceState() должным образом сохраняет состояние виджета в Bundle, но это , а не , переданное MainActivity.onCreate(null).

Создание public class MainActivity extends Activity { ... (вместо public class MainActivity extends AppCompatActivity) устраняет проблему (оно также наносит ущерб ActionBar и другим компонентам, но это уже другая история).

0 голосов
/ 01 марта 2019

Ваша проблема связана с тем, что вы используете «навигацию вверх» (т.е. стрелку в строке меню), а не кнопку «НАЗАД».Я предполагаю, что если вы нажмете кнопку НАЗАД, чтобы вернуться к своему MainActivity, все будет работать так, как вы хотите.

Вы должны просто отключить использование «навигации вверх», удалив:

android:parentActivityName=".MainActivity"

из декларации <activity> в манифесте.

Когда вы узнаете больше о том, как вы можете настроить поведение "навигации вверх", вы сможете убедиться, что при ее использовании вы вернетесь назад,новый экземпляр предыдущего Activity не создается, но существующий экземпляр используется повторно.

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

Я думаю, что вы можете сохранить состояние MainActivity и запустить дочерний процесс с помощью startActivityForResult ().

Вот пример на kotlin (я пропустил несвязанную часть кода):

class ProductDataActivity : BaseActivity(),ProductDataFragment.ProductDataListener {

    private var productData: ProductBinding? = null

    companion object {
        private const val INSTANCE_STATE_PRODUCT_DATA = "state_product_data"
        private const val RESULT_DATA = 1
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        outState?.putSerializable(INSTANCE_STATE_PRODUCT_DATA, this.productData)
        super.onSaveInstanceState(outState)
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        this.productData = savedInstanceState?.getSerializable(INSTANCE_STATE_PRODUCT_DATA) as ProductBinding
        super.onRestoreInstanceState(savedInstanceState)
    }

    override fun onDataClicked() {
        val intent = TabProductDetailsActivity.getCallingIntent(this, productData!!, false)
        this.startActivityForResult(intent, RESULT_DATA)
    }

И другие действия:

class TabProductDetailsActivity : BaseActivity() {

    private var productData: ProductBinding? = null //The activity is started with an intent as you can see above in the ProducDataActivity.

   companion object {
        const val INTENT_EXTRA_PRODUCT_DATA = "intent_product_data"
    }

   override fun onBackPressed() {
        val resultIntent = Intent()
        resultIntent.putExtra(INTENT_EXTRA_PRODUCT_DATA, productData)
        setResult(Activity.RESULT_OK, resultIntent)
        finish()
    }

Надеюсь, вы можете понять, что я здесь делаю, в основном я передаю объект от одного действия к другому, и когда я нажимаю кнопку "Назад"У меня нет проблем с началом деятельности.Не уверен, что это именно то, что вы хотите, но я думаю, что это дает некоторый свет в одном из многих подходов, которые вы можете иметь.

...