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

如何让时钟小部件在后台持续运行且锁屏时不被杀死?

Fixing Clock Widget Freezing on Lock Screen (Process Killed Issue)

Hey there, let's tackle this clock widget problem you're facing—it's super common with aggressive battery optimization on most modern Android devices, especially from Chinese OEMs like Xiaomi, Huawei, or OPPO. Here are actionable steps to keep your widget running reliably even when the screen is locked:

1. First: Tweak System Battery & Permissions Settings

This is the most critical first step—system-level restrictions are usually the main culprit.

  • Enable "Ignore Battery Optimization"
    Go to your device's Settings → Battery → Battery Optimization. Find your widget's parent app, select it, and choose "Don't optimize". This tells the system not to kill your app's background processes to save battery.

  • Allow Background Activity
    Navigate to Settings → Apps → [Your App] → Battery. Make sure "Background activity" is toggled on. For OEM-specific settings:

    • Xiaomi: Go to Settings → Battery & Performance → App Battery Saver → Find your app → Set to "No restrictions".
    • Huawei: Settings → Apps → [Your App] → Launch Management → Switch to "Manual management" and check "Allow background activity".
    • OPPO/Realme: Settings → Battery → App Power Saving → Find your app → Select "No restrictions".

2. Adjust Widget Update Logic (Avoid Persistent Background Processes)

Android doesn't favor apps that keep processes running 24/7. Instead, use system-scheduled tasks to update your widget periodically—this is more reliable and battery-friendly.

Use WorkManager for Periodic Updates

WorkManager is Google's recommended way to schedule deferrable, repeatable tasks. It'll handle wake locks and ensure your widget updates even if the app is killed.

Example Kotlin code for a Worker:

class ClockUpdateWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        // Update your clock widget here
        val appWidgetManager = AppWidgetManager.getInstance(applicationContext)
        val componentName = ComponentName(applicationContext, YourClockWidget::class.java)
        val appWidgetIds = appWidgetManager.getAppWidgetIds(componentName)
        
        YourClockWidget.updateAppWidgets(applicationContext, appWidgetManager, appWidgetIds)
        
        return Result.success()
    }
}

Then schedule the worker in your WidgetProvider's onEnabled method:

override fun onEnabled(context: Context) {
    super.onEnabled(context)
    // Schedule update every 1 minute (adjust interval as needed)
    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.NOT_REQUIRED)
        .build()
    
    val periodicRequest = PeriodicWorkRequestBuilder<ClockUpdateWorker>(1, TimeUnit.MINUTES)
        .setConstraints(constraints)
        .build()
    
    WorkManager.getInstance(context).enqueueUniquePeriodicWork(
        "ClockUpdate",
        ExistingPeriodicWorkPolicy.KEEP,
        periodicRequest
    )
}

// Don't forget to cancel the work when the widget is removed
override fun onDisabled(context: Context) {
    super.onDisabled(context)
    WorkManager.getInstance(context).cancelUniqueWork("ClockUpdate")
}

3. Use a Foreground Service (For Critical Persistence)

If you absolutely need your app's process to stay alive (though this is overkill for most clock widgets), use a Foreground Service. Android treats foreground processes as high-priority and rarely kills them.

  • Add the permission to your AndroidManifest.xml:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  • Create a simple Service that runs in the foreground:
class ClockForegroundService : Service() {
    private val NOTIFICATION_ID = 12345
    private val CHANNEL_ID = "ClockWidgetChannel"

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Create a notification channel (required for Android 8.0+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(CHANNEL_ID, "Clock Widget Service", NotificationManager.IMPORTANCE_LOW)
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }

        // Build a minimal notification
        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Clock Widget Running")
            .setContentText("Keeping your clock updated")
            .setSmallIcon(R.drawable.ic_clock)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build()

        // Start the service in foreground
        startForeground(NOTIFICATION_ID, notification)

        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? = null
}
  • Start this service when your widget is enabled (in onEnabled of your WidgetProvider):
val serviceIntent = Intent(context, ClockForegroundService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(serviceIntent)
} else {
    context.startService(serviceIntent)
}

4. Add a Lock Screen Unlock Refresh

Even if the widget freezes, you can make it instantly update when the user unlocks the screen. Listen for the ACTION_USER_PRESENT broadcast:

  • Register the broadcast in your WidgetProvider's onEnabled method:
val filter = IntentFilter(Intent.ACTION_USER_PRESENT)
context.registerReceiver(clockRefreshReceiver, filter)
  • Create a BroadcastReceiver to trigger the update:
private val clockRefreshReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == Intent.ACTION_USER_PRESENT && context != null) {
            val appWidgetManager = AppWidgetManager.getInstance(context)
            val componentName = ComponentName(context, YourClockWidget::class.java)
            val appWidgetIds = appWidgetManager.getAppWidgetIds(componentName)
            
            YourClockWidget.updateAppWidgets(context, appWidgetManager, appWidgetIds)
        }
    }
}
  • Don't forget to unregister the receiver in onDisabled:
context.unregisterReceiver(clockRefreshReceiver)

Combining these steps should resolve the freezing issue. Start with the battery permission tweaks first—they solve 90% of these cases for most devices.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:25:35