【问题标题】:Notification to resume activity (with data intact)恢复活动的通知(数据完整)
【发布时间】:2014-07-30 17:20:43
【问题描述】:

我已经看到很多关于这个“问题”的问题,但没有任何一个可以完美运行的实际答案。

在我的应用(与健身相关)中,当用户在锻炼期间离开时,我会发出通知,以便他可以快速返回。

Intent intent = new Intent(ctx, WorkoutActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.setClass(ctx, WorkoutActivity.class);
return new NotificationCompat.Builder(ctx)
            .setOngoing(true)
            .setAutoCancel(true)
            .setContentIntent(PendingIntent.getActivity(ctx, 0, intent, 0))
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setSmallIcon(icon);

现在这工作得很好。多亏了Intent 标志,如果活动已启动并正在运行,它就会恢复。

但是我看到的问题是,每当应用程序在后台运行的时间足够长并且操作系统决定终止它时;通过通知输入它将启动一个新的活动实例 - 丢失所有数据。以下是应用在后台后重新进入应用的两种方式,包括我正在寻找的行为。

  1. 按通知。这里出现了问题,因为活动已被销毁并且通知启动了它的一个新的干净实例,但没有保存任何数据。 这是我的问题...
  2. 按下启动器图标。然后您将被带到应用程序的主要活动,并在关闭此活动后,您将被带到活动的破坏版本并重新启动,并恢复所有状态。 这也是我希望它通过通知工作的方式。

此外,我将所有状态保存在 onSaveInstanceState 中,并根据 android 标准使用 onCreate 中的 savedInstanceState 变量恢复它。

这是清单的相关部分:

  <activity
        android:name="workout.progression.ui.workout.WorkoutActivity"
        android:parentActivityName="workout.progression.ui.MainActivity"
        android:theme="@style/AppTheme.WorkoutActivity"
        android:windowSoftInputMode="adjustResize|stateAlwaysHidden"/>

这是根活动:

   <activity
    android:name="workout.progression.ui.MainActivity"
    android:label="@string/app_name"
    android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
     <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
         <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

【问题讨论】:

  • 那么既然您使用的是通知,那么 savedInstanceState 变量是否为空?
  • onSaveInstanceState 保存配置更改,但不会将您从应用程序完全从内存中删除。您如何保存数据?
  • @ianhanniballake 我不会坚持直到锻炼真正完成。然而,作为问题中的#2,活动能够恢复数据,我只想知道它如何通过通知来完成。
  • 那是因为活动还在内存中。一旦从内存中删除,您就可以保存数据。
  • @ianhanniballake 但是它不在内存中,它可以被杀死并仍然恢复它的状态(只要我通过启动器打开它)。

标签: android android-intent android-activity android-notifications


【解决方案1】:

没有办法防止活动被操作系统杀死,但是,您可以将该数据持久保存到其他东西上,例如 SharedPreferences、数据库或文件。以下是关于如何持久化数据的指南:Storage Options。

或者,您可以使用不同的启动模式,例如 单任务:

系统在新任务和路由的根目录创建活动 它的意图。但是,如果活动的一个实例已经 存在,系统通过 调用它的 onNewIntent() 方法,而不是创建一个新方法。

或单一实例:

与“singleTask”相同,只是系统不启动任何其他任务 活动到持有该实例的任务中。活动总是 其任务中唯一且唯一的成员。

但是,这可能会使您的应用程序和活动流的处理方式有些混乱。

参考文献:
Storage Options
Activity Elements: Launch Modes

【讨论】:

  • 但是 onSaveInstanceState 保存了活动的状态,以便以后可以重新创建它,f.x。如果它被操作系统破坏。不需要将值保存到数据库等。这个确切的功能存在于我的应用程序中,正如我之前描述的唯一问题是,每当用户通过通知重新进入应用程序时,都会创建一个新实例(即使旧实例在某个堆栈中)。跨度>
  • 这就是我更新答案以包含其他启动模式的原因。您可以选择最适合您需求的一种。这将允许您处理 onNewIntent() 中的任何更改。另外,我建议查看活动是否在 singleTop 中调用 onNewIntent,我的猜测是,因为它会为您保留状态。
  • 没有使用 SingleTop 启动模式调用 onNewIntent :( 不幸的是,Singleinstance 也没有多大帮助,由于其他原因,它确实不是一个选项。
  • 嗯,在我看来,您需要更改启动模式。我不知道您的要求或限制,但这将保证不会创建任何其他任务或实例。
  • 是的,Android 将删除它存储的所有状态。当然,这种行为也是制造商和手机特定的。此外,如果您的应用程序正在存储状态本身,那么它的行为当然就像 Android 正在保存/恢复状态一样。有关更多信息,请参阅android:alwaysRetainTaskStatedeveloper.android.com/guide/topics/manifest/… 的文档
猜你喜欢
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多