首页 > 解决方案 > 如何重新创建 Android 应用程序类?

问题描述

应用程序类:有时会重新创建

告诉我我是否有这个权利:当启动一个 Android 应用程序时,如果有一个扩展类android.app.Application,则该类将在应用程序启动时创建。但是,如果应用程序没有被使用,那么该实例可能会被删除,然后在应用程序再次进入前台时重新创建。因此,如果之前有任何实例变量被初始化,则不再设置这些变量。

测试应用程序实例重新创建的健壮性

这个问题是关于如何测试以查看应用程序在重新创建其应用程序类的过程中的生存情况。

我发现我可以进入我的应用程序中的一个活动,然后切换到其他应用程序“很长时间”(大约几个小时),当我回来时,我看到构造函数在我的扩展类中运行android.app.Application。问题是我不知道如何强制这种娱乐,以便我可以有效地进行测试。

从各种活动重新开始

我将这一段添加到原始问题中,以提醒人们注意我想要进行的测试。我想在上面进行扩展,我说过“......转到我的应用程序中的一个活动,然后切换(离开我的应用程序).​​.....”。 我们的想法不是杀死整个应用程序并“从顶部”开始。用户在一个活动中,如果Application实例存活,可能会以一种方式运行,但如果Application实例恰好被重新创建,那么可能会以另一种方式运行。

我不是要求在这个问题中解决以下问题(它在其他地方有所介绍)。我要求一个可以在测试中发现此类问题的过程。所以示例:假设Application在初始活动运行时将实例变量保存在实例中。需要该变量的类可以从Application实例中获取它,但前提是初始活动已经设置了它。现在操作系统决定清除并重新创建Application实例。当用户将应用程序带到前台并且他们正在运行一些随机活动(从不通过初始活动的 onCreate() )时,实例变量为空。如果活动编码良好,它不仅会因 NPE 而崩溃。所以我试图测试以确保在上述情况下,实例变量为空,应用程序表现良好。我想我已经知道了,但我想确定一下,我想确定当用户放下手机时,无论正在运行什么活动。

日志的样子

如果应用程序留在其中一个子活动中并且应用程序在后台放置“很长时间”,则操作系统会破坏一些类实例。当应用程序再次获得焦点时,会有一些创建过程。这是日志的样子。

I/zygote: Late-enabling -Xcheck:jni
V/DaleApplication: DaleApplication constructor.
I/InstantRun: starting instant run server: is main process
V/DaleApplication: DaleApplication onCreate. 
V/DaleDatabaseAdapter: constructor.  
V/DaleListActivity: onCreate() is pulling records from the database.
V/DaleListActivity: >>>>>> Selection Args T

您可以看到我将日志记录放入DaleApplicationwhich extends android.app.Application。顺便说一句,我们还看到它还重新创建了数据库适配器并开始从数据库中提取记录,使用户回到所有这些对象被销毁之前的位置。

我在这个问题中寻求的答案将是我可以采取的一些过程,这将使我能够按需破坏类实例,从而使我能够验证重建过程是否正确。

我试过的

尽管我认为杀死整个应用程序是行不通的,但下面的答案建议我尝试一下。但是,我当然需要用户在手机被放下时正在使用的活动来恢复。

1)我尝试通过 adb 杀死:

在让我的 adb.exe 命令行工作后,我能够使用 获取我的应用程序的 pid adb shell,然后 ,in 在pidof ..(aid)..哪里。那回来了。..(aid)..ApplicationIdbuild.gradle13488

我试图使用 杀死应用程序am kill ..(aid)..,但什么也没说,并且 pid 仍然存在。我试过kill 13488了,但那说Operation not permitted-9没有帮助。

编辑:在最终理清要与之交互的 adb.exe 实例之后,我终于得到了这个方法。这相当于按下“终止应用程序”按钮 [参见下面的“3)”项]。

2)我尝试在调试工具窗口中点击“红色方块”:

在调试工具窗口中,我选择了“线程”。里面有一堆东西。我不知道要停止哪个线程来模拟用户放下手机一个小时。停止后main,当我回到手机上的应用程序时,应用程序启动了主要活动(不像重新创建应用程序类时,它启动了之前运行的任何子活动)。

编辑:我认为这不是一个好方法,但这里可能有一些线程不会导致 Android 启动上一个活动而不是最后一个活动。没有进行更多调查,因为这个答案为我解决了问题。

3) Logcat 中的 Terminate App 按钮:

我可以按下手机上的“主页”按钮,然后点击 logcat 窗口中的“红色方块”,但这让我在按下主页按钮时处于活动之前的活动。

Logcat 中的终止应用程序按钮

据我了解,当您从 Android Studio (logcat) 终止应用程序时,Android 假定当前活动表现不佳,因此它不启动它,而是启动前一个活动。 这与长时间搁置手机然后将应用程序恢复到前台时的行为不匹配。

标签: androidandroid-lifecycleandroid-instant-run

解决方案


启动Android应用时,如果有继承android.app.Application的类,该类会在应用启动时创建

更准确地说,该类的一个实例将在您的流程创建时创建。

但是,如果应用程序没有被使用,那么该实例可能会被删除,然后在应用程序再次进入前台时重新创建。

更准确地说,当您的应用程序不在前台时,您的进程可以随时终止(在极少数情况下,即使它在前台)。Application当您的进程执行时,您的所有对象(包括单例)都会消失。您的下一个进程将拥有自己的Application单例。

因此,如果之前有任何实例变量被初始化,则不再设置这些变量。

这在很大程度上取决于它们何时被初始化。例如,如果您在 中初始化它们onCreate(),它们将在您的Application子类的新实例中再次初始化。

如何重新创建 Android 应用程序类?

终止进程。在 Android Studio 中,红色方形“停止”工具栏按钮执行此操作。您也可以从命令行终止进程。在许多情况下,将您的任务从概览屏幕上滑出会终止您的流程。


推荐阅读