在我的应用程序启动时,我想执行一些初始化代码。
我需要初始化:
如您所知,这些是我需要执行的异步任务。
我目前拥有的是MainActivity.onCreate()中的初始化代码,其中包含一个将打开CoreActivity的回调方法。当我对应用程序进行冷启动时,这可以正常工作。
问题从应用程序移动到后台开始,Android可以将其杀死以释放内存。我现在通过禁止Developer options
下的后台进程强制执行此操作。
因此,如果我打开了ExampleActivity并将应用程序移至后台,则当我将其移动到前台时,Android会尝试重新初始化ExampleActivity。这意味着我的应用程序无法正确初始化,因为MainActivity.onCreate()永远不会被执行。
所以我想我可以将初始化代码移到Application.onCreate()。我面临的问题是onCreate()完成执行并在初始化代码仍在运行时打开ExampleActivity。
我注意到在Application.onCreate()中睡眠主线程很糟糕。还有一个观看isInitialized布尔值的while循环永远不会变为真,并以无限循环结束。
我应该如何处理这种情况?
我想做这些步骤
答案 0 :(得分:2)
我的申请多年来一直存在非常接近的问题。即在开始几乎任何活动之前(甚至onResume ...)我需要确保我的应用程序已初始化。 到目前为止,我已经将同步初始化代码的调用插入到许多活动的onCreate方法中(在初始化已经完成的情况下,调用当然立即完成)。
随着应用程序的逐渐增长,初始化需要花费越来越多的时间,这有时会在不同的活动中导致ANR,所以我还需要在任何活动开始时实现异步初始化。
所以,我最近实现了以下方法,可以查看/测试(参见GitHub项目,特别是这个类:MyContextHolder.java)
将对我的静态定义的应用程序初始化代码的调用插入到每个活动的onCreate方法中,这需要初始化应用程序,将调用的Activity实例(this)传递给初始化代码。基本上它看起来像:
if (MyContextHolder.initializeThenRestartMe(this)) {
return;
}
一个。如果已完成初始化,请立即返回 false 。 完成。
湾如果需要初始化,请抓住Activity的启动参数+应用程序的上下文,以便稍后可以重新启动活动。最简单的情况:存储Activity的Intent。 (activity.getIntent()和activity.getApplicationContext())
使用.finish()方法完成尚未显示的Activity。
可选择显示一些"请稍等..."对用户的活动。 (我还不需要这个......)
使用applicationContext在后台线程(专用AsyncTask)中进行应用程序初始化。见MyFutureContext.java)
完成后,使用其存储的参数重新启动Activity。例如。使用存储的Intent和应用程序的Context。像这样: applicationContext.startActivity(意图);
一个有用的提示:为了不看正在重启的闪烁活动,将默认应用程序的主题(在Android Manifest中)设置为透明的。超强!
以下样式定义来自themes.xml文件
<style name="Theme.Transparent" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
答案 1 :(得分:1)
为什么不添加一个会执行INIT或至少听到回调的Splash Activity - INIT_DONE 。收到此类回调后,您就可以开始所需的活动。
通过这个你正在实现以下目标
更新:为什么不从Application.java文件中检查INIT_State。如果app INIT没有完成,则加载基本Activity或Splash,然后应用程序将仅在app init完成的状态下工作。
为了实现这一点,你应该有一个baseActivity,它将被除了splash活动之外的流中的每个其他活动扩展。因此,在每个活动Resume事件中,您可以检查INIT状态,并根据它可以继续加载活动,或者可以将用户重定向到启动屏幕,以便INIT进程完成,然后用户登陆其他活动。
此外,为此您还可以从启动画面启动AppInit进程。这将有助于监控控件,或者您甚至可以将事件用于相同的目的以符合您的设计准则。
答案 2 :(得分:0)
我看到两种选择:
如果“MainActivity被os杀死”
如果不能再次执行Async-stuff: