如何在服务中的工作线程中显示敬酒? [英] How to show a toast from a worker thread inside a service?
问题描述
我正在使用 AlarmManager 唤醒设备并运行一些任务.这些是在 IntentService 内部完成的,因此在与主线程不同的线程上进行.工作完成后,我想敬酒.但是,我收到此日志警告,并且没有显示吐司:
I'm using AlarmManager to wake up the device and run some tasks. These are done inside an IntentService, so on a thread separate from the main one. When the work is done, I'd like to show a toast. However, I'm getting this log warning and no toast is shown:
W/MessageQueue﹕ Handler (android.os.Handler) {b12716d0} sending message to a Handler on a dead thread
java.lang.RuntimeException: Handler (android.os.Handler) {b12716d0} sending message to a Handler on a dead thread
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:320)
at android.os.Handler.enqueueMessage(Handler.java:626)
at android.os.Handler.sendMessageAtTime(Handler.java:595)
at android.os.Handler.sendMessageDelayed(Handler.java:566)
at android.os.Handler.post(Handler.java:326)
at android.widget.Toast$TN.hide(Toast.java:370)
at android.app.ITransientNotification$Stub.onTransact(ITransientNotification.java:55)
at android.os.Binder.execTransact(Binder.java:404)
at dalvik.system.NativeStart.run(Native Method)
我知道关于此主题还有其他一些问题,但是我已经尝试了所有建议,但没有一个起作用.我正在使用:
I know there are a few other questions on this topic, but I've tried all the suggestions and none worked. I'm using:
Handler handler = new Handler();
handler.post(new Runnable()
{
@Override
public void run()
{
Toast.makeText(context, R.string.toast, Toast.LENGTH_LONG).show();
}
});
我也尝试过:
Handler handler = new Handler(Looper.getMainLooper());
我仍然收到警告,没有吐司.
I'm still getting the warning and no toast.
通过我的 IntentService 展示此吐司的方式是什么?
What is the way to show this toast from my IntentService?
提前谢谢!
推荐答案
首先,您真的不应该从服务或用户不久前未发起的任何任务中发送Toast消息.否则,用户将不知道Toast的来源;她甚至无法确定它来自哪个应用程序-绝对令人困惑和不道德的做法.
First of all, you really shouldn't send Toast messages from a Service or from any task that wasn't initiated by the user a very short time ago. Otherwise the user won't know where the Toast is originating from; she can't even be sure from which app it comes - absolutely confusing and bad practice in general.
但是要回答您的问题,当您使用new Handler()
创建处理程序时,它将附加到在其上创建的线程.因此,如果要从服务(从任何线程)向UI/主线程发布某些内容,则应在onCreate()
方法中创建Handler.因为onCreate()
,通常是任何Android回调方法,都是在UI线程上调用的.所以:
But to answer your question, when you create a Handler with new Handler()
then it is attached to the thread it was created on. Thus, if you want to post something to the UI/main thread from a service (from any thread) then you should create the Handler in, for instance, the onCreate()
method; because onCreate()
, and usually any Android callback method, is called on the UI thread. So:
public class MyService extends Service {
private Handler mMainThreadHandler;
@Override
public void onCreate() {
mMainThreadHandler = new Handler();
}
[...]
}
或者,您想要创建一个附加到UI线程的处理程序,并且不想在哪里创建它,那么请使用new Handler(Looper.getMainLooper())
.这样,它就可以连接到主弯针上了.这是主线程的循环程序.
Or, of you want to create a Handler that is attached to the UI thread and don't want to care about where it is created then use new Handler(Looper.getMainLooper())
. This way it is attached to the main looper; which is the looper of the main thread.
public class MyService extends Service {
private Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
[...]
}
我知道您写过它,您曾经尝试过;但应该可以.
I know you wrote you tried it; but it should work.
但是,我建议您不要理会Handlers.改用Needle. Needle是适用于Android的简单而强大的多线程库.有了它,您可以说出类似的话:
Though, what I would recommend you is not to bother with Handlers; use Needle instead. Needle is a simple and powerful multithreading library for Android. With it, you can say things like:
Needle.onMainThread().execute(new Runnable() {
@Override
public void run() {
// e.g. change one of the views
}
});
在GitHub上进行检查: https://github.com/ZsoltSafrany/needle
Check it out on GitHub: https://github.com/ZsoltSafrany/needle
这篇关于如何在服务中的工作线程中显示敬酒?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!