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));
}
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
Handlerand call the post method, passing a new runnable instance that can update your text view. This is a decent tutorial