如何防止 ActivityManager 杀死我的应用程序的后台进程

Posted

技术标签:

【中文标题】如何防止 ActivityManager 杀死我的应用程序的后台进程【英文标题】:How to prevent ActivityManager from killing my application's background process 【发布时间】:2020-07-08 05:52:52 【问题描述】:

我正在开发一个在后台运行的移动应用程序。它每隔一段时间在后台截取屏幕截图,但是一段时间后,ActivityManager 会使用日志终止进程,I/ActivityManager: killing com.example: excessive cpu xxxx during yyyyy dur=zzzzz limit=2

如何防止ActivityManager 杀死应用程序?

我使用 LeakCanary 检查内存泄漏,但发现 0 个泄漏

我试过了: - 缩小启用真 - 收缩资源真实 - proguardFiles

我正在使用Handler 每隔一段时间自动运行我的程序(主要是MediaProjectionImageReader)。在遵循其他问题和谷歌的教程后,我将Handler 设为静态,但同样的问题仍然存在。

MainActivity.java:

    public void startCapturing() 
        try 
            mHandler.post(captureInterval);
            Toast.makeText(this, "started", Toast.LENGTH_SHORT).show();
         catch (Exception e) 
            e.printStackTrace();
        
    

    private static class SafeRunnable implements Runnable 
        private final WeakReference<MainActivity> mReference;

        SafeRunnable(MainActivity reference) 
            mReference = new WeakReference<>(reference);
        

        @Override
        public void run() 
            final MainActivity reference = mReference.get();
            if (reference != null) 
                runWithParent(reference);
            
        
        public void runWithParent(MainActivity reference) 

        
    

    private final Runnable captureInterval = new SafeRunnable(this) 
        @Override
        public void runWithParent(MainActivity reference) 
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
            destroyImageReader();
            destroyVirtualDisplay();
            if (!mKeyguardManager.isKeyguardLocked()) 
                if (mMediaProjection == null) 
                    startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
                 else 
                    createVirtualDisplay();
                
            
            reference.mHandler.removeCallbacksAndMessages(captureInterval);
            reference.mHandler.postDelayed(this, 5000);
        
    ;

【问题讨论】:

“我正在开发一个在后台运行的移动应用程序”——您可能想更详细地解释一下您是如何做到这一点的。你在使用前台服务吗? WorkManager? JobScheduler?还有什么? 嗨@CommonsWare,我已经用运行处理程序的代码更新了问题。我在onCreate() 中实例化Handler。我不使用任何前台服务。 在 Android 中,后台进程一直被终止。这在很多地方都有介绍,比如the documentation、书籍和课程。最接近您的目标的是前台服务。此外,请记住,每 5 秒截取一次屏幕截图每天会消耗约 1GB,具体取决于屏幕分辨率。 【参考方案1】:

正在运行的服务将每 30 分钟终止一次。希望保持活动时间超过此时间的服务必须调用 Service.startForeground,它会在通知栏上放置一个通知,以便用户知道您的服务正在永久运行并且可能会消耗电池寿命。

请向用户显示通知。

希望这会有所帮助。

【讨论】:

将我的代码重构为前台服务后,它就像魅力一样工作。但是,现在存在内存泄漏问题。但这将是另一个问题。感谢您的帮助!

以上是关于如何防止 ActivityManager 杀死我的应用程序的后台进程的主要内容,如果未能解决你的问题,请参考以下文章

用任务管理器杀死时如何防止内存泄漏[重复]

如何防止主线程ios杀死后台线程

我的 Android 小部件被杀死,“不再需要 bellander.andro ....”

弯路:防止通过另一个软件杀死我的软件的任务

防止系统杀死后台应用程序

防止iOS在几分钟后杀死App