向后移动/导航时如何存储/恢复活动状态 [英] How to store/restore activity state when moving/navigating back

查看:69
本文介绍了向后移动/导航时如何存储/恢复活动状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当移至上一个活动(A)时,如何保存活动状态(B)?移回(移至活动B)时如何恢复其先前状态?

场景

活动B的内容可以由用户更改.完成工作后,可以持久保留所做的更改(例如,保存到本地数据库).在保留之前,用户可能需要导航回到上一个活动.此时,应该以某种方式临时的保存工作会议".返回活动B后,应恢复工作会话",以便用户可以继续工作.

方法

标准方法onCreate(Bundle)onSaveInstanceState(Bundle)用于在设备配置更改时(例如在旋转时)恢复/保存活动状态.由于 onSaveInstanceState(Bundle)不属于活动的生命周期,当活动被销毁时(默认情况下称为finish()),不会在按回"时调用此方法. onRestoreInstanceState(Bundle).显然,仅靠这些方法不足以在离开活动后恢复活动状态.

在活动之间转移捆绑包状态

我想到的一种方法是覆盖onBackPressed(),这样它将以当前活动B的捆绑状态Intent#putExtras(Bundle)开始Intent到先前的活动A.活动B,此捆绑包状态将被传递回Intent#putExtras(Bundle)以恢复活动B的状态.但是,这还需要在A中覆盖onCreate(Bundle)onSaveInstanceState(Bundle),因此在导航之前配置更改不会丢失B的捆绑包状态回到B.

未完成后按+非默认launchMode上的活动

另一种方法(更简洁)是覆盖onBackPressed(),以便它将启动Intent至先前的活动A,而无需调用当前活动B的finish(),因此活动B将以暂停状态挂在内存中(等待恢复).要恢复活动B,必须配置清单配置android:launchMode="singleInstance",以便Android在导航回活动B(startIntent(B.class))时将使用现有活动(暂停的B),而不是创建新的活动(B2).

详细信息:launchMode singleInstance创建新任务中的单个活动(任务=具有相同组ID的一组活动,即亲和力,通常应用程序活动具有相同的亲和力,即app =单个任务).

缺点:过渡动画不适用于单实例模式.似乎singleInstance任务可能无法在动画时完全初始化.有关更多详细信息:自定义动画不适用于SingleInstance Activity .. >

将活动状态保存到SharedPreferences

在按下"时将活动状态保存到SharedPreferences,从onCreate(Bundle)中的首选项恢复活动状态,如以下链接共享中列出的某些方法可以使用活动之间的数据.此链接的答案指的是 developer.android.com/guide/appendix/faq/不幸的是,framework.html 损坏了.这是另一种来源 http://wing-linux.sourceforge.net/guide/appendix/faq/framework.html .

关于通过Application对象共享数据:

  • 不要在Application中存储数据对象
  • 使用Android应用程序类临时保留数据.
  • 基于应用程序类文档,使用<>上的strong>静态单例是更可取的.

    用于维护全局应用程序状态的基类. ...

    注意:通常无需子类化Application.在大多数情况下, 静态单例可以在更多模块中提供相同的功能 道路.如果您的单身人士需要全局背景(例如注册) 广播接收器),将Context.getApplicationContext()作为 调用单例的getInstance()方法时的上下文参数.

到目前为止,将数据放入Application对象或静态单例中似乎是针对此问题的最佳解决方案.

问题

是否有任何内置解决方案(无需覆盖onBackPressed())?例如,使用状态将活动保存在后堆栈上.如果不是,在这种情况下保存活动状态的常见模式是什么?

相关帖子(仅用于将其与此帖子相关联)

如何在Android上保存临时数据?

解决方案

退出活动时,不仅会以编程方式销毁该活动,而且还会在概念上销毁该活动.换句话说,用户期望会消失.我们谈论的是在活动对象被销毁但用户认为它仍然存在的情况下保存活动状态,例如在配置更改期间或在后台或后退堆栈中时.

您要保存的内容被正确地认为是应用程序状态,而不是活动状态.因此,SharedPreferences是适合的位置.最佳解决方案是一个问题,取决于您的用例.

How can I save activity state (B) when moving to previous activity (A) and how to restore it's previous state when moving back (to activity B)?

SCENARIO

Content of activity B can be changed by user. After finishing work, performed changes can be persisted (e. g. saved to local DB). Before persisting, user may want to navigate back to previous activity. At this point, "work session" should be somehow saved temporary in memory. After returning back to activity B "work session" should be restored, so user can continue in work.

APPROACHES

Standard methods onCreate(Bundle) and onSaveInstanceState(Bundle) are used to restore/save activity state when device configuration changes (e. g. on rotate). As onSaveInstanceState(Bundle) is not part of activity's life-cycle, this method does not get called on "back-press" when activity is destroyed (by default finish() is called). The same applies for onRestoreInstanceState(Bundle). Obviously these methods alone are not sufficient to restore activity state after lefting an activity.

Transfering bundle state between activities

One way I can think of is to override onBackPressed() in such way it will start an Intent to previous activity A with bundle state Intent#putExtras(Bundle) of current activity B. When moving back, starting an Intent to activity B, this bundle state will be delivered back Intent#putExtras(Bundle) to restore the state of activity B. However this also require to override onCreate(Bundle) and onSaveInstanceState(Bundle) in A so bundle state of B would not be lost on configuration change before navigating back to B.

Not finishing an activity on back-press + non-default launchMode

Another way (more cleaner) is to override onBackPressed() so that it would start Intent to previous activity A without calling finish() of current activity B so activity B will hang in memory in paused state (waiting for resume). To resume activity B, manifest configuration android:launchMode="singleInstance" is required so android will use existing activity (paused B) instead of creating new one (B2) when navigating back to activity B (startIntent(B.class)).

Details: launchMode singleInstance creates singleton activity in new task (task = set of activities with the same group id i. e. affinity, normally app activities have the same affinity i. e. app = single task).

Drawback: transition animations does not work with singleInstance mode. It seems that singleInstance task may not be fully initialized at animation time. For more details: Custom animation doesnt work on SingleInstance Activity.

Saving activity state to SharedPreferences

Saving activity state to SharedPreferences on "back-press", restoring activity state from preferences in onCreate(Bundle) like in following link Save activity state to SharedPreferences.

Drawback: unable to save Bundle state (only primitives: putInt, putString, ...).

Others

Some of the methods listed in Share data between activities can be used. Answers from this link refers to developer.android.com/guide/appendix/faq/framework.html which is unfortunately broken. Here is an alternative source http://wing-linux.sourceforge.net/guide/appendix/faq/framework.html.

About sharing data via Application object:

  • Don't Store Data in the Application Object,
  • Using the Android Application class to temporary persist data.
  • Based on Application class documentation, using static singletons over Application is more preferable.

    Base class for maintaining global application state. ...

    Note: There is normally no need to subclass Application. In most situations, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), include Context.getApplicationContext() as a Context argument when invoking your singleton's getInstance() method.

It seems that putting data in Application object or static singleton is so far the best solution for this problem.

QUESTION

Is there any build-in solution for this (without need of overriding onBackPressed())? For example saving activity on back-stack with it's state. If not, what is the common pattern to save activity state in such situation?

RELATED POSTS (just to link them with this post)

How do I save temporary data on android?

解决方案

When you back out of an activity, the activity is not just destroyed programmatically, but also conceptually. In other words, the user expects it to be gone. We talk about saving activity state in situations where the activity object is destroyed but the user perceives that it still exists, such as during configuration changes or when it's in the background or backstack.

What you're trying to save is properly thought of as application state, not activity state. As such, SharedPreferences is an appropriate place for it. Whether it's the best solution is a matter of opinion and depends on your use case.

这篇关于向后移动/导航时如何存储/恢复活动状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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