You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android ANR崩溃求助:处理SCREEN_ON广播时触发异常

Troubleshooting ANR Triggered by SCREEN_ON Intent in Your Banner Rotation Code

Hey there, let's dig into why this ANR (Application Not Responding) is popping up when the android.intent.action.SCREEN_ON intent fires, and walk through how to fix it.

First, let's identify the root causes in your code:

  • Way too frequent UI thread updates: You're using a Timer that fires every 500ms and posts a Runnable to the UI thread. That's 2 updates per second—way more than necessary for a banner rotation (most apps use 2-3 seconds between slides). When the screen wakes up, the system is already busy with a ton of background tasks, so this constant UI thread chugging is a surefire way to block the main thread and trigger an ANR.
  • Swallowed exceptions: All your catch (Exception e) { } blocks are empty. This hides critical issues like NullPointerException (e.g., if tvBannerText is null because the Activity is destroyed, or bannerList gets cleared unexpectedly) or IndexOutOfBoundsException. These hidden errors can cause silent failures that eat up resources without you knowing.
  • Unmanaged Timer lifecycle: The Timer keeps running even after the Activity is destroyed. It holds a reference to the Activity, causing a memory leak, and keeps trying to update UI elements that no longer exist—wasting CPU cycles and worsening thread congestion.
  • SCREEN_ON broadcast context: This intent is delivered on the main thread. If you're starting this Timer directly from the broadcast receiver, you're adding heavy work to an already busy thread right when the screen wakes up.

Here's how to fix it step by step:

1. Replace Timer with a Handler (Android-friendly alternative)

Timer isn't the best choice for UI-related periodic tasks on Android—Handler is designed to work with the main thread's message queue and is easier to manage.

2. Tie the rotation to the Activity lifecycle

Start the rotation in onResume() and stop it in onPause()/onDestroy() to avoid leaks and unnecessary work when the app isn't visible.

3. Fix exception handling

Log exceptions instead of swallowing them so you can debug issues when they happen.

4. Reduce the rotation interval

Bump it to 2000-3000ms (2-3 seconds) to give the UI thread breathing room.

5. Add null safety checks

Make sure you're not accessing UI elements or data structures that might be null.

Modified code example:

private Handler bannerHandler = new Handler(Looper.getMainLooper());
private Runnable bannerRunnable;

@Override
protected void onResume() {
    super.onResume();
    startBannerRotation();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    stopBannerRotation();
}

private void startBannerRotation() {
    bannerRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                if (bannerList != null && bannerList.size() > 0 && activity != null && !activity.isFinishing()) {
                    int position = bsPromotion.getCurrentSlidePosition() - 1;
                    // Use bannerList size instead of hardcoded 4 to avoid index errors
                    position = position < 0 || position >= bannerList.size() ? 0 : position;
                    
                    if (tvBannerText != null) {
                        tvBannerText.setTag(position);
                        tvBannerText.setText(bannerList.get(position).title);
                    }
                }
                // Schedule next run with a reasonable interval
                bannerHandler.postDelayed(this, 2000);
            } catch (Exception e) {
                // Log the exception to debug issues later
                Log.e("BannerRotation", "Error updating banner text", e);
            }
        }
    };
    // Start the rotation immediately
    bannerHandler.post(bannerRunnable);
}

private void stopBannerRotation() {
    if (bannerHandler != null && bannerRunnable != null) {
        bannerHandler.removeCallbacks(bannerRunnable);
    }
}

Additional tips:

  • If this banner is part of a ViewPager or a dedicated carousel library, use the library's built-in auto-rotation feature instead of rolling your own—those are optimized for performance.
  • If you're starting this from a SCREEN_ON broadcast receiver, don't run the rotation directly there. Instead, send a lightweight signal to your Activity (e.g., via a ViewModel or LocalBroadcastManager) to start the rotation only if the Activity is active.

内容的提问来源于stack exchange,提问作者user1159258

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:25:35