使用服务 IPC 连接调用 CalledFromWrongThreadException
我正在使用教程 此处开发一个服务(现在)只是运行一个TimerTask
来执行System.out.println("tick")
每个第二。除了一些名称更改之外,我的代码与网站上的代码完全相同。如果我不尝试将字符串从服务传递到活动,一切都会正常(服务运行,输出“tick”)。
我想要完成的是在主 Activity 中获取要使用从服务接收到的字符串进行更新的 TextView。我有一个 append(String)
方法工作正常,它将用新文本更新 TextView。因此,在我的服务的 TimerTask
中,我添加了 listener.handleMessage("tick")
并且我的 Activity 实现了侦听器功能:
public void handleMessage(String msg) throws RemoteException {
append(msg);
}
当我运行应用程序时,System. out
显示一个“勾号”,然后显示带有 CalledFromWrongThreadException
的堆栈跟踪,指向 append()
方法作为问题的根源。
我知道有一些关于此异常的问题,但大多数都与 Thread 和 Handler 问题有关;我找不到任何有关服务的信息。有人知道这是否可能吗?
解决方案
扩展 Runnable:
class MyRunnable implements Runnable {
private String msg;
public MyRunnable(String msg) {
this.msg = msg;
}
public void run() {
appendNewline(msg);
}
}
并将回调替换为对全局 Handler 的调用:
public void handleMessage(String msg) throws RemoteException {
handler.post(new MyRunnable(msg));
}
I'm using the tutorial here to develop a Service that is (right now) just running a TimerTask
to do System.out.println("tick")
every second. My code is exactly like the code on the site, aside from some name changes. Everything works (the Service runs, outputs "tick") if I don't try to pass a String from the Service to the Activity.
What I'm trying to accomplish is to get a TextView in the main Activity to be updated with a String received from the Service. I have an append(String)
method working fine that will update the TextView with new text. So in my Service's TimerTask
I've added listener.handleMessage("tick")
and my Activity implements the listener functionality:
public void handleMessage(String msg) throws RemoteException {
append(msg);
}
When I run the application, System.out
shows a "tick", then a stacktrace with the CalledFromWrongThreadException
, pointing to the append()
method as the source of the problem.
I know there's a few questions about this Exception, but most of them concern Thread
and Handler
issues; I couldn't find anything about Services. Anyone know if this is possible?
Solution
Extend Runnable:
class MyRunnable implements Runnable {
private String msg;
public MyRunnable(String msg) {
this.msg = msg;
}
public void run() {
appendNewline(msg);
}
}
and replace the callback with a call to global Handler:
public void handleMessage(String msg) throws RemoteException {
handler.post(new MyRunnable(msg));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对 ui 的更新必须发生在 ui 线程上,而不是后台线程(如计时器的线程)。要更新 ui,请声明
Handler
类型的成员变量并调用 post 方法,传递一个可以更新文本视图的新的可运行实例。这是一个不错的教程Updates to the ui have to occur on the ui thread and not a background thread (like that of the timer). To update the ui, declare a member variable of type
Handler
and call the post method, passing a new runnable instance that can update your text view. This is a decent tutorial