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

Android Service:Timer任务等待BroadcastReceiver响应的问题及优化

Fixing Android Task Interval Issues: Timer → ScheduledExecutorService

As someone new to Android development, my initial implementation using Timer worked most of the time but had occasional odd behavior. Here's the stripped-down version of my first attempt:

private Timer timer;
private TimerTask timerTask;

public void startTimer() {
    timer = new Timer();
    initializeTimerTask();
    timer.schedule(timerTask, 10000, 10000);
}

public void initializeTimerTask() {
    timerTask = new TimerTask() {
        public void run() {
            runSendJob(jsonData, SentReceiver);
            // Wait up to 10 seconds for broadcast receiver response
            long startTime = System.currentTimeMillis();
            while(bResult.equals(false) && (System.currentTimeMillis()-startTime)<10000){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (bResult.equals(true)){
                    UpdateLog();
                }
            }
        }
    };
}

The Problem

When runSendJob plus the wait for the BroadcastReceiver response took 10-20 seconds total, the Timer would trigger the next task immediately after the current one finished—completely ignoring the intended 10-second interval.

The Fix: Switching to ScheduledExecutorService

I redesigned the implementation using ScheduledExecutorService, which handles task scheduling more reliably for long-running operations. Here's the updated code:

public class MyService extends Service {
    BroadcastReceiver SentReceiver;
    public Boolean bResult;
    private Handler mHandler;
    private ScheduledExecutorService mExecutor;
    // Define delays as constants for clarity
    private static final long DELAY_0 = 0;
    private static final long DELAY_10 = 10;
    private static final TimeUnit DELAY_SECONDS = TimeUnit.SECONDS;

    @Override
    public void onCreate() {
        super.onCreate();
        mHandler = new Handler();
        commandStart();
    }

    private void commandStart() {
        if (mExecutor == null) {
            mExecutor = Executors.newSingleThreadScheduledExecutor();
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    startMyTask();
                }
            };
            // Schedule with fixed delay: waits DELAY_10 seconds after the previous task ends
            mExecutor.scheduleWithFixedDelay(runnable, DELAY_0, DELAY_10, DELAY_SECONDS);
            Log.d(TAG, "commandStart: starting executor");
        } else {
            Log.d(TAG, "commandStart: do nothing");
        }

        SentReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                switch(getResultCode()) {
                    case Activity.RESULT_OK:
                        bResult = true;
                        break;
                    case Activity.RESULT_CANCELED:
                        bResult = false;
                        break;
                }
            }
        };
        registerReceiver(SentReceiver, new IntentFilter("MSG_SENT"));
    }

    public void startMyTask() {
        runSendJob(jsonData, SentReceiver);
        // Wait up to 10 seconds for broadcast receiver response
        long startTime = System.currentTimeMillis();
        while(bResult.equals(false) && (System.currentTimeMillis()-startTime)<10000){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (bResult.equals(true)){
                UpdateLog();
            }
            // Spin off other jobs if needed
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    updateSomethingElse();
                }
            });
        }
    }
}

Why This Works

scheduleWithFixedDelay ensures that each task starts only after the previous one has completed plus the specified delay. Unlike Timer.schedule, which schedules based on the start time of the previous task, this matches my requirement of maintaining a consistent 10-second gap between the end of one task and the start of the next.

Since making this change, the service runs reliably with a steady 10-second interval between tasks.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:34:23