我有一些代码在我启动Android活动时运行。如果需要,我将从共享首选项和Web服务器中读取。其中一些将在主线程上发生,显然服务器请求在AsyncTask中。
现在我想知道的是,如果应用程序暂停,会发生什么。字节代码是在程序计数器所在的位置停止还是等待主循环上发生的任何事情完成然后调用onPause。
此外,我担心包括从网络接收数据的回调会发生什么。可以在从暂停恢复后发生回调还是总是丢失?据我了解,在活动暂停时,从网络读取的线程仍然可以运行。
答案 0 :(得分:3)
好吧,我已经做了一些实验,并浏览了一个Activity的Android源代码,现在我更清楚了。
我找到的东西:
onPause,onResume,onStart,onCreate等都在同一个线程内运行(通过打印Thread.currentThread.getId()
),这是主要的事件线程,这个单个事件线程用于所有活动(除非你分配了)清单中的新流程)。这并不完全出乎意料,但我确实想知道onPause是否可能存在于用于停止活动的系统启动线程中。
如果你的代码中有无限的时间(例如onResume或按下按钮后执行的代码),那么onPause和其余部分将永远不会被执行。此外,该循环将继续执行,例如,可以通过每秒打印到日志来看到。如果您要进入主屏幕(或任何其他应该生成onPause甚至onStop的东西),这些打印仍然会发生,并且尽管应用程序不可见,循环仍会继续。你仍然会进入主屏幕。如果你愿意,你可以回到你的应用程序,它仍然会停留在它的循环中。因此,当文档讨论暂停或停止活动的操作时,显然这不会在任何地方停止应用程序执行,或者在主线程中生成运行时异常(在调用onPause之前)或其他任何内容。暂停和查杀活动与linux进程中的概念完全没有关系。
如果我在AsyncTask中运行了一个缓慢的Web请求,那么asynctask代码将在不同的线程中运行,正如您所期望的那样。如果在任务完成其工作之前启动任务的活动暂停,并且onPause,onStop被正常调用,那么当asynctask完成它的回调(在Activity中定义)时,onPostExecute仍将被调用并执行,在主gUI线程。尽管事实上“活动”已经彻底停止了。
我从中得出的结论是,所有onStop和onStart等都只是主事件循环中的事件,就像任何其他事件一样,必须等待在主线程中调用它们。它们不是特别的,不会立即执行或类似的东西,并且可以被循环中的任何其他东西阻挡。
此外,Activity的概念实际上只是一个GUI事物,如果一个Activity被停止,就没有任何屏幕或按钮可以与之交互或显示内容。但是,这与基础流程没有关系,后者将继续处于活动状态并可以打印或响应回调等.JVM继续并且其所有类继续存在并且该流程继续执行。显然,如果没有从GUI接收任何事件或交互并且已经收到onPause,它应该什么都不做。如果它确实占用了任何类型的资源,那么这个过程当然可以被关闭 - 这就是你应该实现生命周期回调的原因。
另外,我们可以在Activity.java中看到暂停是通过调用
来实现的final void performPause() {
mFragments.dispatchPause();
mCalled = false;
onPause();
mResumed = false;
然后到
protected void onPause() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);
getApplication().dispatchActivityPaused(this);
mCalled = true;
}
表明,正如测试所预期的那样,暂停实际上只是将另一个事件调度到主循环。
我认为mCalled变量有两个用途 - 一个用于确保在Activity派生类中调用super()版本,另一个用于系统在销毁需要资源的进程之前检查它是否被调用。
考虑到这是如何工作的,如果onPause很慢,或者被偶数循环中的其他东西阻止了,那么在onPause完成之前你的进程就会被杀死。
显然有些人可能会明白这一点。但我发现文档很混乱。我无法推断我的代码可以进入的状态而不理解运行,暂停等概念在代码排序方面实际意味着什么,因为我认为暂停可能意味着gui线程正在做的运行时异常。
如果我完全误解了这个并且错误的想法请告诉我!我只使用Android 2.5周,很可能我很困惑!