Android:如何从工作线程与服务进行通信 [英] Android: how to communicate from worker thread to a service
问题描述
我创建了一个服务类和一个工作器类,它们在单独的线程中执行.我想在它们之间建立通信,以便工作人员可以将某些状态发送回服务.
I've created a service class and a worker class that is executed in a separate thread. I would like to setup a communication between them, so the worker could send some status back to the service.
我尝试将我的工作人员Thread
转换为HandlerThread
并在服务端设置了Handler
,但是后来我不知道如何实际从工作人员发送消息.看来我无法理解这个概念.
I've tried to convert my worker Thread
to HandlerThread
and setup a Handler
on the service side, but then I don't know how to actually send a message from the worker. It looks like I can't grasp the concept.
这是我的课程(没有通讯逻辑):
Here's my classes (without communication logic):
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");
}
}
工人阶级
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
,从工作线程发送消息并在我的服务中接收消息?
How do I implement a HandlerThread
, send messages from the worker thread and receive them in my service?
我将非常感谢一个代码示例.
I will highly appreciate a code example.
实际上,看来我不能在线程内部使用Looper
,因为它会阻塞线程执行,而我不希望那样.是否可以在不使用Looper
的情况下从线程发送消息?
Actually, it looks like I can't use Looper
inside of my thread cause it will block the thread execution and I don't want that. Is it possible to send messages from the thread without using Looper
?
推荐答案
看来我终于确定了目标!
It looks like I've finally nailed it!
为了将数据从线程传递回服务,您将需要执行以下操作:
In order to pass data from thread back to a service you will need to do this:
-
在服务内部将
Handler
类子类化(例如,将其称为LocalHandler
).您将不得不使其静态.覆盖handleMessage
方法,它将接收来自线程的消息.
Subclass a
Handler
class inside of your service (call it e.g. aLocalHandler
). You will have to make it static. Override ahandleMessage
method, it will receive messages from the thread.
向Thread
构造函数添加Handler
参数.在服务中实例化LocalHandler
类,然后通过构造函数将其注入到线程中.
Add a Handler
argument to your Thread
constructor. Instantiate your LocalHandler
class in a service and inject it to your thread via constructor.
将对Handler
的引用保存在线程内部,并在适当的时候使用它来发送消息.
Save reference to the Handler
inside of your thread and use it to send messages whenever appropriate.
这是完整的示例:
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");
}
}
工人阶级(线程)
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);
}
}
}
我希望这是一个有效的实现.如果您现在采用的是更好的方法-请让我知道.
I hope it's a valid implementation. If you now a better approach - please let me know.
这篇关于Android:如何从工作线程与服务进行通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!