我创建了一个服务类和一个在单独线程中执行的工作类。我想在它们之间建立通信,以便工作人员可以将一些状态发送回服务。
我尝试将我的工作线程 Thread
转换为 HandlerThread
并在服务端设置 Handler
,但后来我没有知道如何实际从工作人员发送消息。看来我无法理解这个概念。
这是我的类(class)(没有通信逻辑):
服务类别
package com.example.app;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class ConnectionService extends Service {
protected ConnectionWorker thread;
@Override
public void onCreate() {
super.onCreate();
// Creating a connection worker thread instance.
// Not starting it yet.
this.thread = new ConnectionWorker();
Log.d(this.getClass().getName(), "Service created");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(this.getClass().getName(), "Service started");
// Checking if worker thread is already running.
if (!this.thread.isAlive()) {
Log.d(this.getClass().getName(), "Starting working thread");
// Starting the worker thread.
this.thread.start();
}
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Log.d(this.getClass().getName(), "Stopping thread");
// Stopping the thread.
this.thread.interrupt();
Log.d(this.getClass().getName(), "Stopping service");
super.onDestroy();
Log.d(this.getClass().getName(), "Service destroyed");
}
}
worker 类(Class)
package com.example.app;
import android.os.SystemClock;
import android.util.Log;
public class ConnectionWorker extends Thread {
public ConnectionWorker() {
super(ConnectionWorker.class.getName());
}
@Override
public void run() {
super.run();
Log.d(this.getClass().getName(), "Thread started");
// Doing the work indefinitely.
while (true) {
if (this.isInterrupted()) {
// Terminating this method when thread is interrupted.
return;
}
// @todo: send a message to the service
Log.d(this.getClass().getName(), "Doing some work for 3 seconds...");
SystemClock.sleep(3 * 1000);
}
}
}
如何实现 HandlerThread
,从工作线程发送消息并在我的服务中接收它们?
我非常感谢代码示例。
更新
实际上,看起来我不能在线程内使用 Looper
因为它会阻止线程执行,而我不希望这样。是否可以在不使用Looper
的情况下从线程发送消息?
最佳答案
看来我终于成功了!
为了将数据从线程传递回服务,您需要执行以下操作:
在服务内部创建
Handler
类的子类(例如,将其称为LocalHandler
)。您必须将其设为静态。重写handleMessage
方法,它将从线程接收消息。向您的
Thread
构造函数添加一个Handler
参数。在服务中实例化您的LocalHandler
类,并通过构造函数将其注入(inject)到您的线程中。保存对线程内部
Handler
的引用,并在适当的时候使用它发送消息。
这是完整的示例:
服务等级
package com.example.app;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
public class ConnectionService extends Service {
protected ConnectionWorker thread;
static class LocalHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Log.d(this.getClass().getName(), "Message received: " + (String) msg.obj);
}
}
protected Handler handler;
@Override
public void onCreate() {
super.onCreate();
// Instantiating overloaded handler.
this.handler = new LocalHandler();
// Creating a connection worker thread instance.
// Not starting it yet.
// Injecting our handler.
this.thread = new ConnectionWorker(this.handler);
Log.d(this.getClass().getName(), "Service created");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(this.getClass().getName(), "Trying to start the service");
// Checking if worker thread is already running.
if (!this.thread.isAlive()) {
Log.d(this.getClass().getName(), "Starting working thread");
// Starting the worker thread.
this.thread.start();
Log.d(this.getClass().getName(), "Service started");
}
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Log.d(this.getClass().getName(), "Stopping thread");
// Stopping the thread.
this.thread.interrupt();
Log.d(this.getClass().getName(), "Stopping service");
super.onDestroy();
Log.d(this.getClass().getName(), "Service destroyed");
}
}
worker 类(线程)
package com.example.app;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
public class ConnectionWorker extends Thread {
// Reference to service's handler.
protected Handler handler;
public ConnectionWorker(Handler handler) {
super(ConnectionWorker.class.getName());
// Saving injected reference.
this.handler = handler;
}
@Override
public void run() {
super.run();
Log.d(this.getClass().getName(), "Thread started");
// Doing the work indefinitely.
while (true) {
if (this.isInterrupted()) {
// Terminating this method when thread is interrupted.
return;
}
Log.d(this.getClass().getName(), "Doing some work for 3 seconds...");
// Sending a message back to the service via handler.
Message message = this.handler.obtainMessage();
message.obj = "Waiting for 3 seconds";
this.handler.sendMessage(message);
SystemClock.sleep(3 * 1000);
}
}
}
我希望这是一个有效的实现。如果您现在有更好的方法 - 请告诉我。
关于java - Android:如何从工作线程到服务进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28915610/