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

应用从后台划走后Service数据重置:亮屏计数功能异常求助

Fixing Screen Count Reset When App is Swiped Away from Background

Hey there! I’ve run into this exact issue before, so let’s break down what’s going wrong and how to fix it.

The Root Problem

When you swipe your app away from the recent apps list, Android often kills the entire app process to free up memory. The onDestroy() method of your Service isn’t guaranteed to run in this scenario—Android can terminate the process abruptly without calling cleanup methods. That’s why your saved count never gets persisted when the app is closed this way.

Step-by-Step Solutions

1. Persist Counts Immediately (Don’t Wait for onDestroy)

Instead of relying on onDestroy() to save your counter, save the value every time it increments. Use SharedPreferences (perfect for small data like this) or a local database like Room to store the count in real time.

Here’s how to implement this in your broadcast receiver:

public class ScreenOnReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
            // Load current count from SharedPreferences
            SharedPreferences prefs = context.getSharedPreferences("ScreenTracker", Context.MODE_PRIVATE);
            int currentCount = prefs.getInt("screen_on_count", 0);
            
            // Increment and save immediately
            currentCount++;
            prefs.edit()
                .putInt("screen_on_count", currentCount)
                .apply(); // Use apply() for async, commit() for sync if needed
            
            // Update your UI here (use ViewModel, LiveData, or LocalBroadcast to notify the activity)
        }
    }
}

2. Initialize Counter from Persistence on App Launch

When your app starts up (e.g., in your main Activity’s onCreate()), load the saved count to restore the previous value:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    TextView countTextView = findViewById(R.id.count_text);
    SharedPreferences prefs = getSharedPreferences("ScreenTracker", Context.MODE_PRIVATE);
    int savedCount = prefs.getInt("screen_on_count", 0);
    
    // Update UI with the saved count
    countTextView.setText(String.format("Screen On Count: %d", savedCount));
}

3. Keep Your Broadcast Receiver Active (Use Foreground Service)

Android 8.0+ restricts background services and dynamic broadcast receivers. To ensure your receiver keeps listening for ACTION_SCREEN_ON even when the app is in the background, run a Foreground Service (which shows a persistent notification to let the user know your app is running).

Here’s how to set up the Foreground Service:

public class ScreenTrackingService extends Service {
    private ScreenOnReceiver screenOnReceiver;

    @Override
    public void onCreate() {
        super.onCreate();
        // Register the broadcast receiver
        IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        screenOnReceiver = new ScreenOnReceiver();
        registerReceiver(screenOnReceiver, filter);
        
        // Create a notification channel (required for Android 8.0+)
        createNotificationChannel();
        
        // Start the service in foreground mode
        Notification notification = new NotificationCompat.Builder(this, "SCREEN_TRACKER_CHANNEL")
                .setContentTitle("Screen Count Tracker")
                .setContentText("Tracking screen on events")
                .setSmallIcon(R.drawable.ic_notification)
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .build();
        startForeground(1, notification);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // Clean up the receiver when service stops
        unregisterReceiver(screenOnReceiver);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    "SCREEN_TRACKER_CHANNEL",
                    "Screen Tracker",
                    NotificationManager.IMPORTANCE_LOW
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
    }
}

Don’t forget to declare the service in your AndroidManifest.xml:

<service
    android:name=".ScreenTrackingService"
    android:foregroundServiceType="dataSync" />

Key Takeaways

  • Never rely on onDestroy() for critical data persistence—Android doesn’t guarantee it will run when the process is killed.
  • Save data incrementally every time the counter changes to avoid losing progress.
  • Use Foreground Service to maintain your broadcast receiver’s activity in the background (compliant with Android 8.0+ restrictions).

内容的提问来源于stack exchange,提问作者Omar El banna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:09:00