簡體   English   中英

后台任務 Android Java,每 X 秒永久

[英]Backgroundtask Android Java, permanent every X seconds

直到現在,我一直使用“AlertManager”來執行后台任務。 這不再適用於新的 Android 版本。 它必須每 15 秒啟動一次,並且在任何情況下都不能被系統停止。 當手機重新啟動時,后台任務也必須啟動。 現在后台任務只啟動一次,然后就什么都沒有發生了。

有解決辦法嗎?

這就是我計划任務的方式:

MainActivity.java

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent startServiceIntent = new Intent(context, hintergrundModus.class);
PendingIntent startServicePendingIntent = PendingIntent.getService(context,0,startServiceIntent,0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
if(alarmManager != null)
alarmManager.set(AlarmManager.RTC_WAKEUP,hintergrundModus.timeHintergrundmodus,startServicePendingIntent);

對於 Android 的較新版本,您需要將androidx.core.app.JobIntentService IntentService (並且不要忘記刪除IntentService#onBind(Intent)的實現,否則您的服務將永遠不會啟動)

class hintergrundModus extends IntentService

    @Override
    protected IBinder onBind(Intent arg0) { 
        return null
    }

    @Override
    protected void onHandleIntent(Intent arg0) {    
        ...
    }
}

會變成

import androidx.core.app.JobIntentService;

class hintergrundModus extends JobIntentService {

    @Override
    public void onHandleWork(Intent arg0) {
        ...
    }
}

對於AlarmManager ,您也將不再使用PendingIntent#getService直接調用您的服務,而是創建一個中介BroadcastReceiver然后可以在調用時將您的工作排入隊列。

import static androidx.core.app.JobIntentService.enqueueWork;

public class ServiceLaunchReceiver extends BroadcastReceiver {

    public static final String RECEIVER_KEY = "com.package.ACTION";
    public static final int UNIQUE_JOB_ID = 0;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(RECEIVER_KEY)) {
            enqueueWork(context, hintergrundModus.class, UNIQUE_JOB_ID , intent);
        }
    }
}

然后可以通過PendingIntent#getBroadcast引用

Intent launcherReceiverIntent = new Intent(context, ServiceLaunchReceiver.class);
PendingIntent startServicePendingIntent = PendingIntent.getBroadcast(context, 0, launcherReceiverIntent, 0);

如果需要重復的計時精度,您可能還想研究在運行 API 19 或更高版本的設備上使用AlarmManager#setExactAlarmManager#setExactAndAllowWhileIdle 然后,您可以在JobIntentService中的工作完成后安排后續警報,而不是安排重復警報。 來自關於AlarmManager#set的注釋:

從API 19開始,傳遞給該方法的觸發時間被認為是不准確的:在此時間之前不會發送警報,但可能會延遲並在一段時間后發送。

您還會發現 Android 的較新版本在終止后台應用程序方面可能非常激進。 由於您的服務似乎是短暫的,因此將其綁定到前台通知(通過startForeground(Int, Notification) )可能對您不起作用。 在這種情況下,您可能需要在運行時向用戶請求電池優化排除,以避免系統限制。

最后,在用於偵聽系統啟動通知的BroadcastReceiver中,實現上述代碼以將新的JobIntentService排隊,或安排第一個警報以將其推遲到以后。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM