Android 如何在应用程序中访问处理程序

Android 如何在应用程序中访问处理程序,android,Android,一个服务中有几个线程在运行。 线程需要将消息发布到UI/Activity 如何将处理程序引用传递给线程?以便他们可以将状态更改发布到“活动”中 或者更好的是,有没有一种方法可以像这样全局公开handler ref Handler getUIHandler(); 先谢谢你;) 在UI线程中创建处理程序对象。如果愿意,您可以在实例化时创建它。从活动启动的任何线程都可以向该处理程序发布消息或可运行文件。从其他活动、服务或诸如此类的活动启动的线程将无法工作,因为无法保证您的活动正在运行。(事实上

一个服务中有几个线程在运行。 线程需要将消息发布到UI/Activity

如何将处理程序引用传递给线程?以便他们可以将状态更改发布到“活动”中

或者更好的是,有没有一种方法可以像这样全局公开handler ref

   Handler getUIHandler();

先谢谢你;)

在UI线程中创建处理程序对象。如果愿意,您可以在实例化时创建它。从活动启动的任何线程都可以向该处理程序发布消息或可运行文件。从其他活动、服务或诸如此类的活动启动的线程将无法工作,因为无法保证您的活动正在运行。(事实上,当活动运行时,看看它是否有效可能是一个有趣的实验,但你永远无法将真正的应用程序建立在这种技术的基础上。)

事实上,您甚至不需要创建处理程序。每个视图对象都包含自己的处理程序,因此您可以简单地将可运行项发布到视图

或者您可以调用
runOnUiThread()

从我关于处理程序的笔记中:

使用模式:

模式1,处理程序和可运行程序:

// Main thread
private Handler handler = new Handler()

  ...

// Some other thread
handler.post(new Runnable() {
  public void run() {
    Log.d(TAG, "this is being run in the main thread");
  }
});
模式2,处理程序加消息:

// Main thread
private Handler handler = new Handler() {
  public void handleMessage(Message msg) {
    Log.d(TAG, "dealing with message: " + msg.what);
  }
};

  ...

// Some other thread
Message msg = handler.obtainMessage(what);
handler.sendMessage(msg);
模式3,调用runOnUiThread():

模式4,使用视图的内置处理程序:

// Some other thread
myView.post(new Runnable() {
  public void run() {
    // perform action in ui thread, presumably involving this view
  }
});

我已经回答了一个类似的问题,即如何向activity报告服务中的错误

检查,这将为您提供一个方法以及一个您可以使用的代码示例


问候。

好的,也许我们应该回到基本问题上来。您是否正在尝试通过服务在活动中进行UI更新?我认为这有两种方法

首先,您的服务可以将特殊意图发送回活动。以“singleTask”的启动模式声明活动,并实现onNewIntent()以接收来自服务的意图。然后,将任何相关信息打包到意图中,并将其发送给要处理的活动

更好的方法是从活动中绑定服务,这样它们就可以通过绑定器轻松地相互通信,但要复杂一些。如果服务和活动都是同一个应用程序的一部分,并且都在同一个进程中运行,这将变得简单得多

同样,从我的笔记中:

声明一个名为“LocalBinder”的内部类,该类扩展了Binder,并包含一个名为getService()的方法,该方法返回服务实例:

public class MyService extends Service
{
  public class LocalBinder extends Binder {
    MyService getService() {
      return MyService.this;
    }
  }

  private final IBinder binder = new LocalBinder();

  public IBinder onBind(Intent intent) {
    return binder;
  }
}
您的活动包含如下代码:

// Subclass of ServiceConnection used to manage connect/disconnect
class MyConnection extends ServiceConnection {
  public void onServiceConnected(ComponentName name, IBinder svc) {
    myService = ((MyService.LocalBinder)svc).getService();
    // we are now connected
  }
  public void onServiceDisconnected(ComponentName name) {
    // we are now disconnected
    myService = null;
  }
}

private MyService myService;
private MyConnection connection = new MyConnection();

/**
 * Bind to the service
 */
void doBind() {
  bindService(new Intent(MyClient.this, MyService.class),
    connection, Context.BIND_AUTO_CREATE);
}

/**
 * Unbind from the service
 */
void doUnbind() {
  if (connection != null) {
    unbindService(connection);
  }
}

查看前面的讨论。谢谢,我喜欢您发布的模式,但我想问的是如何访问线程中的处理程序引用。如果线程驻留在与活动属于同一进程的服务中,我们是否仍然不确定活动是否存在???即使服务是??据我所知,同一进程的服务和活动共享同一线程。不是吗?如果服务是从“活动”启动的,则“活动”可能在服务运行时仍然存在,但没有保证。正如我所说的,这将是一个有趣的实验,看看服务中的线程是否可以访问活动中的处理程序,但如果没有这些保证,就没有什么意义了。进一步思考一下:第一种方法的优点是,它可以在UI更新时将您的活动重新显示在屏幕上,第二种方法的优点是,如果活动退出,您可以安排服务退出。
// Subclass of ServiceConnection used to manage connect/disconnect
class MyConnection extends ServiceConnection {
  public void onServiceConnected(ComponentName name, IBinder svc) {
    myService = ((MyService.LocalBinder)svc).getService();
    // we are now connected
  }
  public void onServiceDisconnected(ComponentName name) {
    // we are now disconnected
    myService = null;
  }
}

private MyService myService;
private MyConnection connection = new MyConnection();

/**
 * Bind to the service
 */
void doBind() {
  bindService(new Intent(MyClient.this, MyService.class),
    connection, Context.BIND_AUTO_CREATE);
}

/**
 * Unbind from the service
 */
void doUnbind() {
  if (connection != null) {
    unbindService(connection);
  }
}