管理android活动栈:一个活动的特定实例如何把自己带到前台?



我有一组要在它们之间导航的活动,由于初始化这些活动的成本很高,所以如果可能的话,我希望保留现有状态。问题是,我可能有相同的活动打开了不止一次,在每个不同的状态,我没有看到一个方法,标准的Android标志可以帮助我解决这种情况。

下面是一个可视化的例子:

假设我有三个活动:

A, B, C

这些活动中的每一个都可以打开多次,每个活动都保持不同的状态。这些活动不仅初始化成本高,而且我还想维护用户的当前状态,如滚动位置,选中的项目等。

假设A(1)是状态1下活动A的实例,A(2)是状态2下活动A的实例。A(1)与B(1)不相关。

我想实现一个循环导航堆栈如下:

…——>(1)->(2)——> B(1) ->(2)——> B(3)——>(3)——> C (1) -> (1 ) --> ...

由于活动是昂贵的,我真的希望只是重用现有的实例。然而,我可能需要保留大约2或3个相同活动的实例,就像你上面看到的那样。

谢谢!

这实际上是可能的,但你需要使用反射和Intent。FLAG_ACTIVITY_MULTIPLE_TASK国旗。

我是这样做的:

Controller:用Intent启动activity。意图。FLAG_ACTIVITY_MULTIPLE_TASK

Activities:通过传入唯一的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来控制。

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

在AndroidManifest.xml中,你可以定义应用程序的每个活动,运行时系统应该如何启动特定的活动。在你的例子中,你应该用"singleTask"的值来定义你的activity的launchMode属性。这样,运行时系统就不会创建特定活动的多个实例。每次,当特定的活动应该启动时,运行时系统将调用onNewIntent()活动。在这个方法中,你可以处理一个特定活动的不同状态。

可以这样做:不允许一个特定活动的实例超过1个。当你通过设置launchMode在manifest中声明每个活动时,你就可以做到这一点。然后,通过创建一个包含每个activity Bundle对象的应用程序范围对象来跟踪实例状态。当打开一个activity时,传递给它一个合适的Bundle。

最新更新