【发布时间】:2016-01-23 13:48:11
【问题描述】:
我有一个以 Activity 开头的应用程序,用于在显示主 Activity 之前加载内容。启动应用程序通常是MyApplication --> MyLoadingActivity --> MyMainActivity。在MyMainActivity 中有一个带有 RecyclerViews 和其他东西的 ViewPager。 MyMainActivity 中的状态在导航到应用程序中的其他 Activity 和从其他 Activity 导航时会被正确保存和恢复,但是当从 Notification 启动 MyMainActivity 时,所有状态都会被清除,因为 Android 会重新启动该 Activity。
通知是从检查远程服务器更新的服务创建的。找到更新后,新数据将存储在 SQLite 数据库中,并创建有关此的通知。单击此通知时,MyMainActicity 启动,但状态丢失。
按照official guide,下面是我在服务中创建通知的方法:
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.foo)
.setAutoCancel(true)
.setContentTitle("title")
.setContentText("text")
.setStyle(new NotificationCompat.BigTextStyle().bigText("A long text will go here if we are on Lollipop or above."));
Intent notifyIntent = new Intent(context, MyMainActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifyPendingIntent = PendingIntent.getActivity(context, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(notifyPendingIntent);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(666, builder.build());
我尝试以各种方式组合Intent.FLAG_***,但我无法使其正常工作。我无法弄清楚这一点,因此提出了这个问题。
我在打开通知时想要实现的是:
- 如果应用程序没有运行,正常启动应用程序并转到
MyMainActivity。 - 如果应用程序正在运行并且
MyMainActivity处于活动状态,只需将其放在前面以现有状态运行几行代码。 - 如果应用程序正在运行,而另一个 Activity 正在运行,则返回
MyMainActivity,最好使用现有堆栈。大多数其他活动都是MyMainActivity的子项。
使用当前代码会发生什么:
- 使用
Intent.FLAG_ACTIVITY_NEW_TASK创建一个MyMainActivity的new 实例,该实例具有空状态,即使它的描述状态为
当使用这个标志时,如果一个任务已经在为这个活动运行 您现在正在开始,则不会开始新的活动; 相反,当前任务将简单地被带到前面 屏幕显示上次所处的状态。
- 在创建新的
MyMainActivity后,还使用Intent.FLAG_ACTIVITY_CLEAR_TASK在现有MyMainActivity上调用onDestroy()。这没有多大帮助。
我还尝试了哪些其他方法:
A.如here 所述,将 Intent 设置为像应用程序通常那样启动是行不通的。
B.各种标志组合都无法提供所需的行为。
C. Stackoverflow 上的各种其他答案。
作为参考,这是我的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my.app"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/my_app_name"
android:theme="@style/MyTheme"
android:name=".MyApplication" >
<activity
android:name=".activities.MyLoadingActivity"
android:icon="@drawable/ic_launcher"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.MyMainActivity"
android:icon="@drawable/ic_launcher"
android:label="@string/my_app_name"
android:screenOrientation="portrait" >
</activity>
<activity
android:name=".activities.AnotherActivity"
android:label="@string/aa_title"
android:icon="@drawable/ic_launcher"
android:parentActivityName=".activities.MyMainActivity"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MyMainActivity" >
</meta-data>
</activity>
<!-- More children activities of MyMainActivity here -->
<receiver android:name=".services.ScheduleUpdateReciever">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="com.my.app.action.ScheduleUpdateReceiver"/>
</intent-filter>
</receiver>
<receiver android:name=".services.StartUpdateReceiver" />
<service android:enabled="true" android:name=".services.UpdateService" />
</application>
</manifest>
更新:保存/恢复
这是MyMainActivity 的保存和恢复方式。我意识到这可能需要一些清洁。也许这与问题有关。为简洁起见,省略了类的其他部分。如上所述,在应用内导航时,所有保存和恢复都可以正常工作。
private ShoppingList mShoppingList;
private FilteredRecipes mFilteredRecipes;
private MainFragment mMainFragment;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity_layout);
// Start the Broadcast receiver that creates notifications if new data is found.
startService(new Intent(this, ScheduleUpdateReciever.class));
sendBroadcast(new Intent(SCHEDULE_UPDATE_RECEIVER_BROADCAST));
// Setup Toolbar, NavigationView, DrawerLayout etc. here. No state restored for these widgets.
if (mShoppingList == null)
{
mShoppingList = new ShoppingList(this);
}
if (mFilteredRecipes == null)
{
mFilteredRecipes = new FilteredRecipes(this);
}
if (savedInstanceState == null)
{
mMainFragment = new MainFragment();
}
else
{
restoreState(savedInstanceState);
}
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_frame, mMainFragment, FragmentConstants.MAIN_FRAGMENT_TAG)
.commit();
}
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
// These calls adds stuff directly to the Bundle instance, be it basic variables, lists or Parcelable classes.
mShoppingList.onSaveInstanceState(outState);
mFilteredRecipes.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, SAVE_RESTORE_MAIN_FRAGMENT, mMainFragment);
}
private void restoreState(Bundle savedInstanceState)
{
// These calls restores stuff directly from the Bundle instance, be it basic variables, lists or Parcelable classes.
mShoppingList.onRestoreInstanceState(savedInstanceState);
mFilteredRecipes.onRestoreInstanceState(savedInstanceState);
mMainFragment = (MainFragment) getSupportFragmentManager().getFragment(savedInstanceState, SAVE_RESTORE_MAIN_FRAGMENT);
}
【问题讨论】:
-
从/到另一个活动时,您如何恢复/保存 MyMainActicity 的状态?您是否使用数据库中的意图、sharedPreferences 和值?如果是这样,您是在 onCreate、onStart 还是 onResume 中恢复 MyMainActicity?
-
您是否尝试过使用标志:FLAG_ACTIVITY_SINGLE_TOP 和 FLAG_ACTIVITY_CLEAR_TOP 比如:intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-
有关保存和恢复状态的信息,请参阅上面的更新。此过程中不涉及 Intent、SharedPreferences 或数据库调用。我将状态保存在
onSaveInstanceState()并在onCreate()中恢复状态。onResume()和onStart()均未实现。 -
我编辑了我的答案,如果您需要任何关于如何使用 sharedPreferences 保存状态的具体示例,请告诉我:)
标签: android android-intent android-notifications