handler.postDelayed 在 IntentService 的 onHandleIntent 方法中不起作用

问题描述 投票:0回答:7
final Handler handler = new Handler();
LOG.d("delay");
handler.postDelayed(new Runnable() {
    @Override public void run() {
        LOG.d("notify!");
        //calling some methods here
    }
}, 2000);

“延迟”确实显示在日志中,但其他根本不显示。并且

run()
中调用的方法也根本没有被调用。谁能帮忙解释一下为什么会发生这种情况,我做错了什么吗?

有这段代码的类扩展了IntentService,这会是一个问题吗?

==============================

更新: 我将这段代码放在扩展

IntentService
的类中。我发现它唯一有效的地方是在构造函数中。但我需要把它放在
onHandleIntent
方法中。所以我检查了
onHandleIntent
的文档,它说:

此方法在工作线程上调用,并发出要处理的请求。一次仅处理一个 Intent,但处理发生在独立于其他应用程序逻辑运行的工作线程上。因此,如果此代码需要很长时间,它将阻止对同一 IntentService 的其他请求,但不会阻止其他任何请求。当所有请求都处理完毕后,IntentService 会自行停止,因此您不应该调用 stopSelf。

所以根据我得到的结果,我觉得我不能在“工作线程”中使用

postDelayed
。但任何人都可以解释一下这一点,比如为什么这在工作线程中不起作用?预先感谢。

android intentservice android-handler android-intentservice postdelayed
7个回答
17
投票

转换

final Handler handler = new Handler();

final Handler handler = new Handler(Looper.getMainLooper());

这对我有用。


12
投票

您正在使用主线程的循环程序。您必须创建一个新的循环程序,然后将其交给您的处理程序。

HandlerThread handlerThread = new HandlerThread("background-thread");
handlerThread.start();
final Handler handler = new Handler(handlerThread.getLooper());
handler.postDelayed(new Runnable() {
    @Override public void run() {
        LOG.d("notify!");
        // call some methods here

        // make sure to finish the thread to avoid leaking memory
        handlerThread.quitSafely();
    }
}, 2000);

或者你可以使用Thread.sleep(long millis)。

try {
    Thread.sleep(2000);
    // call some methods here

} catch (InterruptedException e) {
    e.printStackTrace();
}

如果您想停止休眠线程,请使用

yourThread.interrupt();


1
投票

这就是我使用处理程序的方式:

import android.os.Handler;

Handler handler;
//initialize handler
handler = new Handler();

//to start handler
handler.post(runnableName);

private Runnable runnableName= new Runnable() {
        @Override
        public void run() {
            //call function, do something
            handler.postDelayed(runnableName, delay);//this is the line that makes a runnable repeat itself
        }
};

0
投票

设备屏幕打开时,处理程序和服务将是可预测的。 例如,如果设备进入睡眠状态,处理程序将不是一个可行的解决方案。

更好、更可靠的解决方案是使用:

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);


0
投票

IntentService
不是为这种情况设计的。您可以使用常规的
Service
代替。您可以将处理程序放入
onStartCommand()
内。别忘了 在服务实例上调用
stopSelf()
以在
handler.postDelayed(){}

之后将其关闭

0
投票

最简单的是先等待再结束onHandleIntent():

SystemClock.sleep(2000);

0
投票

我的回答没有回答您的特定问题。

为需要安排多个任务且延迟较小并从

handler.postDelayed
获得意外行为的任何人添加它。

我试图以固定的延迟来执行任务。我使用 for 循环尝试了下面的代码,它只是安排所有任务以总和(延迟)运行。后来我用递归修复了它。

For 循环代码(NOT 工作)

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)
        val handler = Handler(Looper.getMainLooper())
        // code to fetch instructions from intent
        var cummulativeDelay = 0L
        for (instruction in instructions) {
            val handler = Handler(Looper.getMainLooper())
            handler.postDelayed({
                executeInstruction(instruction)
            }, cummulativeDelay)
            cummulativeDelay += instruction.delay
        }
    }

递归代码(有效)

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)
        val handler = Handler(Looper.getMainLooper())
        // code to fetch instructions from intent
        executeInstructions(instructions, 0, handler)
    }

    private fun executeInstruction(instruction: Instruction) {
        // execute the instruction
    }

    private fun executeInstructions(instructions: List<Instruction>, i: Int, handler: Handler) {
        if (i == instructions.size) {
            stopSelf()
            return
        }
        val instruction = instructions[i]
        try {
            executeInstruction(instruction)
        } catch(e: Exception) {
            e.printStackTrace()
        }
        val delay = /* delay in milliseconds */
        handler.postDelayed({
            executeInstructions(instructions, i+1, handler)
        }, delay)
    }

是因为批量处理延迟较小的延迟指令吗?

© www.soinside.com 2019 - 2024. All rights reserved.