【发布时间】:2019-05-28 03:50:58
【问题描述】:
应用程序类:有时会重新创建
告诉我我是否有这个权利:当启动一个 Android 应用程序时,如果有一个扩展 android.app.Application 的类,该类将在应用程序启动时创建。但是,如果应用程序没有被使用,那么该实例可能会被删除,然后在应用程序再次进入前台时重新创建。所以如果有任何之前初始化过的实例变量,这些变量就不再设置了。
测试应用实例重新创建的健壮性
这个问题是关于如何测试一个应用程序在重新创建它的应用程序类的过程中的生存情况。
我发现我可以进入我的应用程序中的一个活动,然后切换到其他应用程序“很长时间”(大约几个小时),当我回来时,我看到构造函数在我的类中运行扩展android.app.Application。问题是我不知道如何强制进行这种重新创建以便有效地进行测试。
从各种活动重新开始
我将这一段添加到原始问题中,以提醒人们注意我想要进行的测试。我想在上面进行扩展,我说过 “...转到我的应用程序中的一个活动,然后切换(离开我的应用程序)...”。 这个想法不是杀死整个应用程序并开始'从顶部开始'。用户在一个 Activity 中,如果 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
你可以看到我把登录放到了DaleApplication,它扩展了android.app.Application。顺便说一句,我们还看到它还重新创建了数据库适配器并开始从数据库中提取记录,使用户回到所有这些对象被销毁之前的位置。
我在这个问题中寻求的答案是我可以采取的一些过程,它允许我按需破坏类实例,从而使我能够验证重建过程是否正确。
我的尝试
虽然我认为杀死整个应用程序是行不通的,下面的答案建议我尝试一下。但是,我当然需要用户在手机被放下时正在使用的活动来恢复。
1) 我尝试通过 adb 杀死:
在让我的 adb.exe 命令行工作后,我能够使用 adb shell 和 pidof ..(aid).. 获取我的应用程序的 pid,其中 ..(aid).. 是 ApplicationId 中的 build.gradle。这返回了13488。
我尝试使用am kill ..(aid).. 杀死应用程序,但什么也没说,并且 pid 仍然存在。我试过kill 13488,但那是Operation not permitted。 -9 没有帮助。
编辑:在最终理清要与之交互的 adb.exe 实例之后,我终于让这个方法起作用了。这相当于按下“终止应用程序”按钮 [参见下面的“3)”项]。
2) 我尝试在调试工具窗口中点击“红色方块”:
在调试工具窗口中,我选择了“线程”。里面有一堆东西。我不知道要停止哪个线程来模拟用户放下手机一个小时。在停止main 之后,当我回到手机上的应用程序时,应用程序启动了主活动(不像重新创建应用程序类时,它会启动之前运行的任何子活动)。
编辑:我认为这不是一个好方法,但这里可能有一些线程不会导致 Android 启动上一个活动而不是最后一个活动。没有进行更多调查,因为this answer为我解决了问题。
3) Logcat 中的终止应用按钮:
我可以按手机上的“主页”按钮,然后点击 logcat 窗口中的“红色方块”,但这让我进入了活动之前我当时正在进行的活动按下主页按钮。
据我了解,当您从 Android Studio (logcat) 终止应用程序时,Android 会假定当前 Activity 的行为不正常,因此它没有启动它,而是启动了 以前的活动。 这与长时间搁置手机后应用恢复到前台的行为不符。
【问题讨论】:
标签: android android-lifecycle android-instant-run