使用处理程序线程避免 SCREEN_ON 上的 ANR

Posted

技术标签:

【中文标题】使用处理程序线程避免 SCREEN_ON 上的 ANR【英文标题】:Avoid ANR on SCREEN_ON using Handler Thread 【发布时间】:2021-11-02 09:06:15 【问题描述】:

获取 ANR,执行 Intent.ACTION_SCREEN_ON 的阻塞/重度调用。下面是代码

    private static BroadcastReceiver mScreenOnReceiver = new BroadcastReceiver() 
    @Override
    public void onReceive(Context context, Intent intent) 
        String action = intent.getAction();
        if (action.equals(Intent.ACTION_SCREEN_ON))               
                // Blocking operation
        
    

为了避免 ANR,我打算将阻塞操作移到工作线程中。下面的代码是否有助于避免 ANR?

private static BroadcastReceiver mScreenOnReceiver = new BroadcastReceiver() 
    @Override
    public void onReceive(Context context, Intent intent) 
        String action = intent.getAction();
        if (action.equals(Intent.ACTION_SCREEN_ON))               
                new Handler().post(new Runnable() 
                    @Override
                    public void run() 
                        //Blocking operation
                    
                );
        
    

【问题讨论】:

【参考方案1】:

没有。 BroadcastReceivers 是短暂的。无法保证托管您的BroadcastReceiver 的操作系统进程的寿命足以执行此代码。不仅如此,您还将在主 (UI) 线程上运行此代码,这是您无法阻止的(您的 Runnable 不会在“工作线程”中运行,它将在主 (UI) 线程中运行)。

您的BroadcastReceiver 应该启动一个Service,它可以运行一个后台(工作)线程来执行您的阻塞操作。或者您可以使用JobScheduler 来安排此操作(如果它适合您的目的)。

【讨论】:

以上是关于使用处理程序线程避免 SCREEN_ON 上的 ANR的主要内容,如果未能解决你的问题,请参考以下文章

事务 - 如何避免死锁?

怎么处理JAVA多线程死锁问题?

使用 TCP 处理多个线程

java.lang.RuntimeException:处理程序(android.os.Handler)向死线程上的处理程序发送消息

Google App Engine 上的错误 Python 2.7 - 无法使用 CGI 处理程序启用线程安全

进程线程与处理器的调度