管理android活动堆栈:活动的特定实例如何将自己带到前端?

时间:2011-08-26 16:07:20

标签: android user-interface android-activity navigation stack

我有一组我在其间导航的活动,并且由于这些活动初始化起来很昂贵,我想尽可能保留现有状态。问题是我可能会多次打开相同的活动,每个活动都有不同的状态,而且我没有看到标准Android标志可以帮助我解决这种情况的方法。

这是一个直观的例子:

想象一下,我有三项活动:

A,B,C

这些活动中的每一个都可以不止一次打开,每个活动都持有不同的状态。这些活动不仅初始化起来很昂贵,而且我还想维护用户的当前状态,例如滚动位置,所选项目等......

假设A(1)是状态1中活动A的实例,A(2)是状态2中活动A的实例.A(1)和B(1)是无关的。

我想按如下方式实现循环导航堆栈:

... - > A(1) - > A(2) - > B(1) - > B(2) - > B(3) - > A(3) - > C(1) - > A(1) - > ...

由于活动很昂贵,我真的很想重用现有的实例。但是,我可能需要保留大约2或3个相同活动的实例,如上所示。

谢谢!

4 个答案:

答案 0 :(得分:4)

好的,所以这实际上是可行的,但你需要使用反射和Intent.FLAG_ACTIVITY_MULTIPLE_TASK标志。

我是这样做的:

Controller:使用Intent.FLAG_ACTIVITY_NEW_TASK |启动活动Intent.FLAG_ACTIVITY_MULTIPLE_TASK

活动:通过传入唯一ID来识别他们的状态,并使用getTaskId()

来识别他们的任务ID,从而向控制器注册自己

Controller:如果任务已经死亡,则创建一个活动(它使用ActivityManager.getRunningTasks()进行检查)。如果任务仍然存在,那么它使用以下反射代码将任务放在前面:

Class ActivityManagerNative = Class.forName("android.app.ActivityManagerNative");

Method getDefault = ActivityManagerNative.getMethod("getDefault", null);
Object activityManagerNative = getDefault.invoke(ActivityManagerNative, null);

Method[] methods = activityManagerNative.getClass().getMethods();

Method moveTaskToFront;

for (final Method method : methods) { if (method.getName().equals("moveTaskToFront")) { moveTaskToFront = method;}}

...

moveTaskToFront.invoke(activityManagerNative, registeredTaskId);

可以通过从请求更改任务的活动中调用overridePendingTransition来控制动画。

希望这可以帮助其他人。

答案 1 :(得分:2)

moveTaskToFront.invoke仅在API 11之后可用。如何在API 8级应用程序中实现相同功能。

答案 2 :(得分:1)

在AndroidManifest.xml中,您可以为应用的每个活动定义运行时系统应如何启动特定活动。在您的情况下,您应该使用值“singleTask”定义活动的launchMode属性。然后,运行时系统将不会创建特定活动的多个实例。每次启动特定活动时,运行时系统都会启动onNewIntent()活动。在该方法中,您可以处理一个特定活动的不同状态。

答案 3 :(得分:0)

可能有用的是:不允许超过1个特定活动的实例。通过设置launchMode在清单中声明每个活动时,可以执行此操作。然后,通过创建包含每个活动Bundle对象的应用程序范围对象来跟踪实例状态。打开活动时,请将相应的Bundle传递给它。