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 我认为您不应该将Thread
和Handler
组合在一起。他们有点做同样的事情,所以你只需要选择使用哪一个。【参考方案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() 方法中的 delayMillis 参数实际上代表啥?
Handler的postDelayed(Runnable, long)
Android Studio - 如何从片段中停止 handler.postDelayed?