我有一个应用程序,其中的入口点是“login / splash” Activity
,我需要从服务器预加载新数据。此SplashActivity
声明为:
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
在我的AndroidManifest.xml
中,加载数据后,我会在自定义Application
课程中保留一些数据,然后继续我的MainActivity
。
我期待,在我的Application
被操作系统或用户(使用强制停止)停止后,然后由用户重新启动,我的应用程序的入口点为{ {1}}再次但是系统会跳过SplashActivity
并显示SplashActivity
。
问题:这是预期的行为吗?如果整个过程停止,我的应用程序不应该以{{1}}启动吗?这可以实现吗?
答案 0 :(得分:27)
实际上,这个问题及其中的一些答案可以解决几个问题:
要回答您的原始问题,“是的,这是预期的行为”。
Android认为每个Activity都是一个独立的自包含实体。 Android会记住任务堆栈中的活动状态,它可以随时杀死您的进程(包含您的所有活动),因为它“知道”它可以随时重建您的活动。当然,当您拥有一个复杂的应用程序时,这个概念会破坏您在活动之间存在依赖关系和/或您拥有存储在Application
类(或类似的静态/单一位置)中的全局数据。
当Android杀死您的进程时,它会记住任务中最重要的活动,当用户返回任务时,它会重新创建该进程,然后重新创建 任务中最顶层的活动。在您的情况下,MainActivity
。
例如,如果您的任务堆栈如下所示:
StartActivity -> ActivityB -> ActivityC -> ActivityD
并且您的任务进入后台并且Android终止了该过程,当用户返回任务时,将仅重新创建ActivityD
。完成ActivityD
后,Android会重新创建ActivityC
。完成ActivityC
后,Android会重新创建ActivityB
等。简而言之,当用户恢复任务时,完整的堆栈不会重新创建。
没有清单设置或Intent标志的组合可以获得您想要的行为。如果Android提供类似的东西会很好,但目前它没有。
您可以通过在Application派生类(或任何其他类)中使用静态(类)布尔变量来确定您的进程是否已重新启动。重新启动进程时,此变量将始终具有值false
,然后您可以从任何位置检查变量的状态,并在必要时重新初始化(重新加载数据)。然后将变量设置为true
。它将保持true
,直到该进程被终止并重新创建,即使您的所有活动都已完成。这样,您只能在需要时进行初始化。
您也可以将此作为指标从SplashScreen
重新启动您的应用程序。因此,在onCreate()
中的所有活动中,您可以检查此布尔变量的状态,如果应用程序已重新启动,您只需重定向到SplashScreen
,如下所示:
Intent intent = new Intent(this, SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
这将完成任务中的所有活动,并在任务的根目录重新启动SplashScreen
。
接下来,如果您想要防止每次用户返回应用程序时(当它在后台并随后被AndroidOS杀死时)下载数据,您应该将下载的数据存储在私有缓存区域中并在重新启动应用程序时使用它。这可以防止在您的进程被终止并重新启动时不得不重复下载数据。
处理此问题的另一种方法是在服务中加载数据。如果您的流程中有Service
正在运行,则Android不太可能会终止您的流程。您只需确保在用户完成应用程序时关闭Service
。
我意识到这个答案是啰嗦的。希望你能从中获得一些东西。
答案 1 :(得分:0)
可以这样做:
1。 SplashActivity
每次都会毫无疑问。
2. 下载数据并保存检查(布尔值),表示之前已完成加载。您可以使用SharedPreferences。
3。下次检查条件并立即开始MainActivity
。