从服务线程更改主活动 UI 的方法

4

我已经寻找了相当长一段时间,寻找一些好的文档或示例。我需要从在后台运行的服务中的工作线程中更改主活动UI。据我所知,我应该使用某种处理程序来处理此问题,但我不确定如何处理。

是否有任何想法或好的示例可以指导我?我正在更改的UI元素是一个TextView,仅向用户显示线程的状态。

感谢您的帮助。

4个回答

7
您只需在UI线程上创建一个Handler即可:
private Handler serviceHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        someFunctionInTheUIThread();
    }
};

然后将其传递到您的服务中。您可以在服务中拥有这样一个函数:

public void registerHandler(Handler serviceHandler) {
    handler = serviceHandler;
}

然后像这样传递处理程序:
theService = ((LocalBinder) service).getService();
theService.registerHandler(serviceHandler);

然后发送一条回复消息:

Message msg = handler.obtainMessage(IDENTIFIER, "Message or data");
handler.sendMessage(msg);

我从服务的线程还是从onStartCommand发送消息有关系吗?我计划从两者都发送。 - gtdevel
Handlers的美妙之处在于它们可以跨线程工作 - 在这里阅读http://developer.android.com/reference/android/os/Handler.html。 "Handler允许您发送和处理与线程的MessageQueue相关联的Message和Runnable对象。每个Handler实例都与单个线程及其消息队列相关联。当您创建新的Handler时,它绑定到创建它的线程/消息队列 - 从那时起,它将向该消息队列传递消息和可运行项,并在它们从消息队列中出来时执行它们。" - Martyn
那么,如果我的服务中有一个工作线程,它并不在同一个线程中运行,是吗?这是否意味着我需要创建两个处理程序来从服务方法和线程发送消息?抱歉,如果这些问题很愚蠢,但线程让我感到困惑。 - gtdevel
不需要。在第一个线程(可能是您的UI线程)上创建“Handler”,然后将处理程序传递到服务中的工作线程。它应该可以正常工作 :) - Martyn
LocalBinder是什么?在使用以下代码之前,我需要在我的服务中编写一些代码吗? theService = ((LocalBinder) service).getService(); theService.registerHandler(serviceHandler); - gtdevel
请查看此页面上的示例:http://developer.android.com/reference/android/app/Service.html - Martyn

2

请了解服务绑定(Service Binding)。或者您可以在主活动中使用广播接收器(BroadcastReceiver)接收服务的广播。


1
你需要在服务中使用sendBroadcast(intent)发送一个意图,然后在你的活动中设置一个广播接收器。

我尝试过了,但是遇到了一些问题。我将尝试使用处理器,看看能否使广播接收器正常工作...谢谢。 - gtdevel

1
在您的主Activity中的onCreate()方法中创建一个Handler。这将在UI线程中创建一个处理程序。然后从工作线程使用此处理程序,调用任何需要更新TextView的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接