Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何模拟Android杀死我的进程_Android - Fatal编程技术网

如何模拟Android杀死我的进程

如何模拟Android杀死我的进程,android,Android,如果进程在后台,并且操作系统决定它需要资源(RAM、CPU等),Android将杀死该进程。我需要能够在测试期间模拟这种行为,以便确保我的应用程序正常运行。我希望能够以一种自动化的方式完成这项工作,这样我就可以测试应用程序是否在任何时候都能正常运行,这意味着我必须在每个活动中测试它,等等 我知道如何终止我的进程。这不是问题所在。问题是,当我终止进程时(使用DDMS、adb shell kill、process.killProcess(),等等),Android不会像Android操作系统自己终止

如果进程在后台,并且操作系统决定它需要资源(RAM、CPU等),Android将杀死该进程。我需要能够在测试期间模拟这种行为,以便确保我的应用程序正常运行。我希望能够以一种自动化的方式完成这项工作,这样我就可以测试应用程序是否在任何时候都能正常运行,这意味着我必须在每个活动中测试它,等等

我知道如何终止我的进程。这不是问题所在。问题是,当我终止进程时(使用DDMS、
adb shell kill
process.killProcess()
,等等),Android不会像Android操作系统自己终止进程时那样重新启动进程

如果Android操作系统终止进程(由于资源需求),当用户返回应用程序时,Android将重新创建进程,然后重新创建活动堆栈上的顶部活动(调用
onCreate()

另一方面,如果I杀死进程,Android假设活动堆栈顶部的活动表现不好,因此它会自动重新创建进程,然后从活动堆栈中删除顶部活动,并重新创建顶部活动下方的活动(调用onCreate()`)。这不是我想要的行为。我想要的行为与Android终止进程时的行为相同

仅作图示说明,如果我的活动堆栈如下所示:

    ActivityA -> ActivityB -> ActivityC -> ActivityD
如果Android终止进程,用户返回应用程序,Android将重新创建进程并创建ActivityD


如果我终止进程,Android将重新创建进程并创建ActivityC。

在“设置”下的“开发人员选项”中,选择“不保留活动”,这将在您离开活动时立即销毁活动


注意:根据下面一条有用的注释,仅当您不关心清除静态值时才使用此选项。

问题的根源似乎是您的
活动在终止进程时处于前台

活动
可见时(发生与您描述的完全相同),您可以通过在DDMS中按stop键观察到这一点,并将其与回家后按stop键以及稍后返回应用程序进行比较


只需确保在测试中以某种方式
moveTaskToBack(true)

您可以执行以下步骤来重现所寻求的行为:

  • 打开你的应用程序,导航到顶级活动
  • 使用通知面板导航到任何其他全屏应用程序(例如,导航到系统设置-在右上角)
  • 终止您的应用程序进程
  • 按后退按钮

  • 对我来说,最好的测试方法是:

    • 在应用程序中打开ActivityD
    • 按主页按钮
    • 在Android Studio的Logcat窗口中按
      终止应用程序
      (这将终止应用程序进程,请确保在顶部的Logcat下拉列表中选择您的设备和进程)
    • 长按主页或打开应用程序返回应用程序(取决于设备)
    • 应用程序将在重新创建的ActivityD中启动(ActivityA、ActivityB、ActivityC已死亡,将在您返回时重新创建)
    在某些设备上,您还可以通过应用程序->启动器图标返回应用程序(ActivityD),但在其他设备上,它将启动ActivityA

    这就是安卓文档所说的:

    通常,在某些情况下,当用户从主屏幕重新选择某个任务时,系统会清除该任务(从根活动上方的堆栈中删除所有活动)。通常,如果用户在一定时间内(如30分钟)未访问该任务,则会执行此操作


    按下Home(主页)按钮,首先将应用程序置于后台。然后停止或终止DDMS或ADB的进程。

    我不确定这是否是您要寻找的答案,这更像是一种逻辑思考

    我不认为你真的可以做一个完全自动化的测试,模拟它的唯一方法是重新创建它,因为有太多的活动,Android会杀死你的应用程序

    <start app from launcher first time>
    Application onCreate
    ActivityA onCreate WITHOUT savedInstance
    ActivityA onStart
    <open ActivityB>
    ActivityB onCreate WITHOUT savedInstance
    ActivityB onStart
    ActivityA onStop
    ActivityA onDestroy (do not keep)
    <return launcher by home button>
    ActivityB onStop
    ActivityB onDestroy (do not keep) 
    <retun app from recent apps>
    // NO Application onCreate
    ActivityB onCreate WITH savedInstance (user does not notice activity recreated)
    ActivityB onStart
    <return ActivityA by back>
    ActivityA onCreate WITH savedInstance (user does not notice activity recreated)
    ActivityA onStart
    ActivityB onStop
    ActivityB onDestroy
    <press back again, return launcher>
    ActivityA onStop
    ActivityA onDestroy
    <open app again>
    //does not call Application onCreate, app was not killed
    ActivityA onCreate WITHOUT savedInstance
    ActivityA onStart
    
    因此,我的想法或建议是制作另一个小应用程序,它不断弹出新的活动,直到Android内存耗尽并开始在后台停止处理

    其中有一句话:


    启动活动i->检查正在运行的流程如果应用程序在列表中,则增加i并重新启动循环而不关闭当前活动,否则->减少i并关闭当前活动,返回上一步并重新检查…

    这似乎对我有效:

    adb shell am kill <package_name>
    
    因此,如果进程在前台,它不会终止进程。这似乎是OP想要的,因为如果我离开我的应用程序,然后运行
    adb shell am kill
    它将终止应用程序(我已经在设备上使用
    ps
    确认了这一点)。然后,如果我返回到应用程序,我将回到以前的活动中-即,在OP的示例中,该过程将被重新创建并创建ActivityD(而不是像大多数其他杀人方法一样触发ActivityC)


    很抱歉,我的OP迟了几年,但希望其他人会发现这很有用。

    另一种方法,可能是一种可编写脚本的方法,因为它不需要DDMS:

    一次性设置:转到开发人员选项,选择后台进程限制设置,将值从“标准限制”更改为“无后台进程”


    当您需要重新启动进程时,按home按钮。进程将被终止(您可以在studio中的logcat/Android监视器中进行验证——进程将被标记为[DEAD])。然后使用任务切换器切换回应用程序。

    您也可以使用
    adb shell
    从终端连接到您的设备/仿真器,然后使用
    ps | grep获取您的流程PID。我参加聚会已经很晚了,而且在几天之前
    
    <start app from launcher first time>
    Application onCreate
    ActivityA onCreate WITHOUT savedInstance
    ActivityA onStart
    <open ActivityB>
    ActivityB onCreate WITHOUT savedInstance
    ActivityB onStart
    ActivityA onStop (the order is like this, it is stopped after new one is started)
    <go settings>
    ActivityB onStop
    <disable a permission>
    //Application is killed, but onDestroy methods are not called.
    //Android does not call onDestroy methods if app will be killed.
    <return app by recent apps>
    Application onCreate (this is the important part. All static variables are reset.)
    ActivityB onCreate WITH savedInstance (user does not notice activity is recreated)
    //Note that ActivityA is not created yet, do not try to access it.
    ActivityB onStart
    <return ActivityA by back>
    ActivityA onCreate WITH savedInstance (user does not notice activity is recreated)
    ActivityA onStart
    ActivityB onStop
    ActivityB onDestroy
    <press back again, return launcher>
    ActivityA onStop
    ActivityA onDestroy
    <open app again>
    //does not call Application onCreate, app was not killed
    ActivityA onCreate WITHOUT savedInstance
    ActivityA onStart
    
    <start app from launcher first time>
    Application onCreate
    ActivityA onCreate WITHOUT savedInstance
    ActivityA onStart
    <open ActivityB>
    ActivityB onCreate WITHOUT savedInstance
    ActivityB onStart
    ActivityA onStop
    ActivityA onDestroy (do not keep)
    <return launcher by home button>
    ActivityB onStop
    ActivityB onDestroy (do not keep) 
    <retun app from recent apps>
    // NO Application onCreate
    ActivityB onCreate WITH savedInstance (user does not notice activity recreated)
    ActivityB onStart
    <return ActivityA by back>
    ActivityA onCreate WITH savedInstance (user does not notice activity recreated)
    ActivityA onStart
    ActivityB onStop
    ActivityB onDestroy
    <press back again, return launcher>
    ActivityA onStop
    ActivityA onDestroy
    <open app again>
    //does not call Application onCreate, app was not killed
    ActivityA onCreate WITHOUT savedInstance
    ActivityA onStart
    
    <start app from launcher first time>
    Application onCreate
    ActivityA onCreate WITHOUT savedInstance
    ActivityA onStart
    <open ActivityB>
    ActivityB onCreate WITHOUT savedInstance
    ActivityB onStart
    ActivityA onStop
    <go settings>
    ActivityB onStop
    <force stop, return app from recent apps>
    Application onCreate
    ActivityA onCreate WITHOUT savedInstance 
    //This is important part, app is destroyed by user.
    //Root activity of the task is started, not the top activity.
    //Also there is no savedInstance.
    
     adb shell am kill [my-package-name]
    
    class TerminatorActivity : Activity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            val isPrePie = applicationInfo.targetSdkVersion < Build.VERSION_CODES.P
            val callbacks = TerminatorLifecycleCallbacks(isPrePie)
            (applicationContext as Application).registerActivityLifecycleCallbacks(callbacks)
        }
    
        private class TerminatorLifecycleCallbacks(
            // Before P onSaveInstanceState() was called before onStop(), starting with P it's
            // called after
            // Used to schedule the death as app reports server that activity has stopped
            // after the latest of these was invoked
            private val isPrePie: Boolean
        ) : ActivityLifecycleCallbacksDefault {
    
            private val handler = Handler(Looper.getMainLooper())
    
            override fun onActivityPostStopped(activity: Activity) {
                if (isPrePie) {
                    terminate()
                }
            }
    
            override fun onActivityPostSaveInstanceState(activity: Activity, outState: Bundle) {
                if (!isPrePie) {
                    terminate()
                }
            }
    
            fun terminate() {
                handler.postDelayed(
                    {
                        Process.killProcess(Process.myPid()) // This is the end... 
                    },
                    LAST_MILLIS
                )
            }
    
            companion object {
                // Let's wait for a while, so app can report and server can handle the update
                const val LAST_MILLIS = 100L
            }
    
        }
    
        private interface ActivityLifecycleCallbacksDefault : Application.ActivityLifecycleCallbacks {
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
            override fun onActivityStarted(activity: Activity) {}
            override fun onActivityResumed(activity: Activity) {}
            override fun onActivityPaused(activity: Activity) {}
            override fun onActivityStopped(activity: Activity) {}
            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
            override fun onActivityDestroyed(activity: Activity) {}
        }
    }