Android中的activity的堆栈有啥作用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中的activity的堆栈有啥作用相关的知识,希望对你有一定的参考价值。

有flag标志位控制堆栈中的activity存放顺序,这样做有什么作用呢。

我的理解是堆栈就是后进先出,那么稍微想像一下,你打开的Activity是一层一层往上盖的,当你退出当前这个Activity的时候,使用堆栈机制才会显示你底下那一层的Activity,提高Activity复用率吧。如果你觉得这个Activity可以不用再保留那么也给你提供了相应的打开另一个Activity之后就清理掉自己的方法。这样做的用户体验会比较好吧;那么反过来讲如果没有采用堆栈机制,在这么有限的显示区域里应该怎么去分配多个Activity呢? 参考技术A android是通过将之前的activity组件和新被激活的activity组件放入同一个任务栈来实现这个功能的。从用户的角度看,一个任务栈就代表了“一个应用程序”。它实际上是一个栈,里面放着一组被排列好的相关的activity组件。位于栈底的activity(根activity)就是开启这个任务栈的activity组件,一般情况下,就是应用程序的主界面。而位于栈顶的activity组件即代表当前被激活的activity组件(可接收用户行为的activity)。
任务栈中包含了activity组件的对象,且任务栈中可以包含有某一个activity组件类型的多个实例对象。在任务栈中的activity组件不能被重排序,只能被压栈和弹栈。

Android Activity Stack 未按文档中的说明工作 - 未显示任务堆栈中的最后一个活动

【中文标题】Android Activity Stack 未按文档中的说明工作 - 未显示任务堆栈中的最后一个活动【英文标题】:Android Activity Stack is not working as stated in the docs - last activity in task stack not shown 【发布时间】:2012-06-15 22:02:37 【问题描述】:

根据 Android 文档:

http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html

"当用户按下 Home 按钮离开任务时,当前活动停止,其任务进入后台。系统保留任务中每个活动的状态。如果用户稍后通过选择恢复任务启动任务的启动器图标,任务进入前台并恢复堆栈顶部的活动。”

如果我理解正确,这意味着:

    活动 A 作为主要活动。 在 A 中通过“startActivity”启动的活动 B - 常见的、普通的意图实例。 我第一次打开应用程序,A 被加载。 我点击A中的按钮,B是openend。 我按下主页按钮。 我第二次再次打开应用程序,预计会显示 B

...对吗? 我想这是期望的正确行为......

但是,我没有在我的应用中看到这个。

如果我点击“主页按钮”然后通过按下启动器图标恢复我的应用程序,它将从主要活动开始 - 而不是顶部的活动或最新的活动。

我在三星 Galaxy Tab Android 2.2.1 上进行编码 - 我在 Android 清单中有最常见的选项 - 事情是我处理了 10 个不同的活动,具有不同的意图额外内容 - 以及一个 Dispatcher 类方法 - 或保存每个活动状态 - 听起来要求很高。

我正在使用带有 ADT 版本 12 的 Eclipse IDE;我发现了一些非常有趣的东西:

当我从 Eclipse IDE 运行应用程序并连接我的设备时,我看不到这种行为。该应用程序的行为如文档中所述。 事实上,我是在将我的 apk 部署到 Google Play 应用程序存储库后才看到这一点的;下载下来测试一下。

我的问题是,有没有人找到发生这种情况的真正原因? 文档有错吗?还是遗漏了什么? 这是 Android 上的错误吗?

我做过的另一项研究是:

当我尝试从 google play 下载的 APK 应用程序时,如果我第二次进入我的应用程序,我会得到“主要”活动,而不是最后一个 openend。我按回家。 按主页后,我进入android的应用程序管理设置,找到我的应用程序并单击“强制停止”。 执行此操作后,应用程序的行为如文档中所述。

有人帮忙! :)

【问题讨论】:

【参考方案1】:

这是android平台的一个bug:

http://code.google.com/p/android/issues/detail?id=2373

解决方法是将其放在主 Activity 的 onCreate 方法中:

if (!isTaskRoot())

    final Intent intent = getIntent();
    final String intentAction = intent.getAction(); 
    if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN))
    
        Log.w(LOG_TAG, "Main Activity is not the root.  Finishing Main Activity instead of launching.");
        finish();
        return;       
    

摘自:

How to prevent multiple instances of an activity when it is launched with different intents

...花了 3 天时间寻找这个。

【讨论】:

只要确保你的清单尽可能“简单”——不要在你的活动标签上添加任何启动修饰符。 完美答案,轻松解决了我们3天的问题。谢谢! 该死的,我试图弄清楚过去两天发生了什么,如果我找不到那个答案,我可能会花更多的钱.. 非常感谢伙计!当您将用户重定向到应用程序外部的某个位置时,它似乎也适用,例如 gps 设置和用户使用后退按钮返回应用程序。我想知道为什么重新创建了活动但未提供状态包【参考方案2】:

我将解释它失败的原因,以及如何以编程方式重现此错误,以便您可以将其合并到您的测试套件中:

    当您通过 Eclipse 或 Market App 启动应用程序时,它会以意图标志启动:FLAG_ACTIVITY_NEW_TASK。

    通过启动器(主页)启动时,它使用标志:FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_BROUGHT_TO_FRONT | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,并使用操作“MAIN”和类别“LAUNCHER”。

如果您想在测试用例中重现这一点,请使用以下步骤:

adb shell am start -f 0x10000000 -n com.testfairy.tests.regression.taskroot/.MainActivity 

然后做任何需要做的事情来进行其他活动。出于我的目的,我只是放置了一个按钮来启动另一个活动。然后,返回启动器(主页):

adb shell am start -W -c android.intent.category.HOME -a android.intent.action.MAIN

并通过启动器模拟启动它:

adb shell am start -a "android.intent.action.MAIN" -c "android.intent.category.LAUNCHER" -f 0x10600000 -n com.testfairy.tests.regression.taskroot/.MainActivity

如果您没有合并 isTaskRoot() 解决方法,这将重现问题。我们在自动测试中使用它来确保此错误不再发生。

希望这会有所帮助!

【讨论】:

【参考方案3】:

文档是正确的,我能想到的唯一可能的问题是您正在测试的设备,如果它在模拟器(即普通 Android)上按预期工作,它应该在至少 90% 上工作Android,这是制造商的错,我相信不是 Android。

【讨论】:

感谢您的回复。我怀疑是当我通过 Eclipse 安装应用程序时,我可能会遇到与我看到的相同的行为。也许我应该尝试通过模拟器命令上传 APK,看看会发生什么...... 是的,我在模拟器上有预期的行为......但是为什么它在设备上发生了变化......??另外,您是否阅读过我提到的“强制停止”操作?这真的很奇怪。到目前为止,我已经在 2.3.X 和 2.1 的 2 部 HTC 手机上进行了测试......以及 2.3.X 的 LG ......我没有得到预期的行为......当我按下主页并返回时到应用程序,它加载 MAIN 活动而不是堆栈顶部的最新活动:S 您的活动中没有调用完成的内容吗?该应用程序刚刚从应用程序堆栈中删除。 看我的回答,我不敢相信,但是是的,这是android平台的一个错误...... 看起来它已经被报告了两次......这真的很随机​​且令人沮丧......我认为它与设备型号或任何东西有关......感谢您关注SmartLemon: D

以上是关于Android中的activity的堆栈有啥作用的主要内容,如果未能解决你的问题,请参考以下文章

Android 任务栈

android 清单文件有啥作用? widget相对位置的完成在activity的哪个生命周期阶段实现?

回到Android中的后备堆栈中的不同Activity

Android 返回堆栈管理打印 Android 中当前运行的 Activity 任务栈信息 | Activity 任务栈信息分析 | Activity 在相同 Stack 中的不同 Task(代码片

Android Activity Stack 未按文档中的说明工作 - 未显示任务堆栈中的最后一个活动

onsavelnstancestate有啥作用?如何使用