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
。但任何人都可以解释一下这一点,比如为什么这在工作线程中不起作用?预先感谢。
转换
final Handler handler = new Handler();
到
final Handler handler = new Handler(Looper.getMainLooper());
这对我有用。
您正在使用主线程的循环程序。您必须创建一个新的循环程序,然后将其交给您的处理程序。
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();
这就是我使用处理程序的方式:
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
}
};
设备屏幕打开时,处理程序和服务将是可预测的。 例如,如果设备进入睡眠状态,处理程序将不是一个可行的解决方案。
更好、更可靠的解决方案是使用:
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
IntentService
不是为这种情况设计的。您可以使用常规的 Service
代替。您可以将处理程序放入 onStartCommand()
内。别忘了
在服务实例上调用 stopSelf()
以在 handler.postDelayed(){}
之后将其关闭
最简单的是先等待再结束onHandleIntent():
SystemClock.sleep(2000);
我的回答没有回答您的特定问题。
为需要安排多个任务且延迟较小并从
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)
}
是因为批量处理延迟较小的延迟指令吗?