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

Posted

技术标签:

【中文标题】handler.postDelayed 在 IntentService 的 onHandleIntent 方法中不起作用【英文标题】:handler.postDelayed is not working in onHandleIntent method of IntentService 【发布时间】:2016-08-25 06:12:07 【问题描述】:
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。但是任何人都可以解释一下,比如为什么这在工作线程中不起作用?提前致谢。

【问题讨论】:

是从os.Handler 导入的? @NJ 是的。 android.os.Handler 你在哪里打电话?需要上下文。 为什么@Override 在 public 旁边而不是在上面?为什么是 "LOG.d" 而不是 "Log.d("your tag", "notify!")" ?如果您确实导入了 os.Handler 那么它应该可以工作。 IntentService 通常用于不需要与主线程通信的长任务。也许解释一下你想要达到的目标 【参考方案1】:

转换

final Handler handler = new Handler();

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

这对我有用。

【讨论】:

只要您在主线程中实例化处理程序,这不会有任何区别。 @CopsOnRoad 会有所作为,IntentService 的 onHandleIntent 在自己的线程中运行。【参考方案2】:

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

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();

【讨论】:

【参考方案3】:

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

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
        
;

【讨论】:

感谢您的回答,但它不起作用。我不知道是不是因为我不能把这个人放在一些线程或其他东西中。 但我无法在我的项目中导入 android.os.Handler。 在调用handler.post之前不应该分配runnableName吗? @kbsbng 不,只是把它当作一种方法。 @Zip 我认为您不应该将ThreadHandler 组合在一起。他们有点做同样的事情,所以你只需要选择使用哪一个。【参考方案4】:

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

一个更好、更可靠的解决方案是使用: AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

【讨论】:

如果你想延迟几秒钟就不行 你有这个声明的参考吗?我在问,因为我的处理程序在大约之后无法预测地工作。屏幕关闭 15 分钟【参考方案5】:

IntentService 不是为这种情况设计的。您可以改用常规的Service。您可以将处理程序放在onStartCommand() 中。不要忘记 在服务实例上调用stopSelf() 以在handler.postDelayed() 之后将其关闭

【讨论】:

【参考方案6】:

最简单的就是在结束前等待onHandleIntent()

SystemClock.sleep(2000);

【讨论】:

以上是关于handler.postDelayed 在 IntentService 的 onHandleIntent 方法中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

停止 handler.postDelayed()

Handler.postDelayed() 方法中的 delayMillis 参数实际上代表啥?

Handler的postDelayed(Runnable, long)

Android Studio - 如何从片段中停止 handler.postDelayed?

Android Handler.removeMessage移除所有postDelayed的问题

android postDelayed实现