我有Service
启动处理网络活动的新Thread
。我将Activity
,Service
和Thread
全部放在不同的文件中。我正在尝试使用通过传递Messenger
扩展Messenger
而创建的Handler
来设置它们之间的通信。我已经弄清楚如何让Service
和Activity
很好地交谈,但是我无法弄清楚如何给我的Service
目标以允许它发送消息单独的Thread
。
这就是我现在正在尝试的内容,但是Service
到Thread
的邮件永远不会发送...
服务
public class TCPSocketService extends Service {
//Messengers
private Messenger clientMessenger;
private Messenger socketMessenger;
//Message Incoming Handlers
private Messenger clientIncomingHandler;
private Messenger socketIncomingHandler;
@Override
public void onCreate() {
Log.d("Service", "TCPSocketService created");
isConnected = false;
clientIncomingHandler = new Messenger(new ClientToServiceIncomingHandler());
}
@Override
public IBinder onBind(Intent intent) {
return clientIncomingHandler.getBinder();
}
/*
* Event Handlers for Messages received from Client
*/
/**
* Called when {@link Service} receives the HELLO message from Client
* Registers {@link Messenger} that represents the Client's Incoming Message Handler
*
* @param msg {@link Message} object containing {@link Messenger} for responses
*/
private void onHello(Message msg) {
registerClient(msg.replyTo);
}
/**
* Called when {@link Service} receives the START_THREAD message from Client
* Initializes and starts a new {@link Thread} with {@link SocketThread} class
*/
private void onStartThread() {
socketThread = new SocketThread(ip, port);
new Thread(socketThread).start();
socketMessenger = new Messenger(new SocketToServiceIncomingHandler(socketThread.getLooper()));
//Tell Client thread has started
Message msg = Message.obtain();
msg.what = Event.THREAD_STARTED;
messageClient(msg);
}
/**
* Called when {@link Service} receives the CONNECT message from Client
* Sends the {@link Thread} a {@link Message} telling him to connect to server
*/
private void onConnect() {
Message msg = Message.obtain();
msg.what = Event.CONNECT;
msg.replyTo = socketMessenger;
messageSocket(msg);
}
/*
* Support functions
*/
/**
*
* @param client
*/
private void registerClient(Messenger client) {
clientMessenger = client;
Message msg = Message.obtain();
msg.what = Event.HELLO;
messageClient(msg);
}
/**
*
* @param msg
*/
private void messageClient(Message msg) {
try {
clientMessenger.send(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @param msg
*/
private void messageSocket(Message msg) {
try {
socketMessenger.send(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Incoming Handler for messages coming from Client
*/
private class ClientToServiceIncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case Event.HELLO:
Log.d("Service", "Client said HELLO");
onHello(msg);
break;
case Event.START_THREAD:
Log.d("Service", "Client said START_THREAD");
onStartThread();
break;
case Event.CONNECT:
Log.d("Service", "Client said CONNECT");
onConnect();
default:
Log.e("Service", "Client said some weird shit");
super.handleMessage(msg);
}
}
}
/**
* Incoming Handler for messages coming from Socket
*/
private class SocketToServiceIncomingHandler extends Handler {
public SocketToServiceIncomingHandler(Looper mainLooper) {
super(mainLooper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Event.CONNECTED:
Log.d("Service", "Socket said CONNECTED");
onConnected();
break;
case Event.DISCONNECTED:
Log.d("Service", "Socket said DISCONNECTED");
onDisconnected();
break;
default:
super.handleMessage(msg);
}
}
}
}
发
public class SocketThread implements Runnable {
//Properties
private Handler serviceIncomingHandler;
//Target to send Messages to Serivce
private Messenger serviceMessenger;
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
Log.d("Socket", "New thread started...");
Looper.prepare();
serviceIncomingHandler = new ServiceToSocketIncomingHandler();
Looper.loop();
}
/*
* Event Handlers for Messages from Service
*/
private void onConnect(Messenger serviceReplyTo) {
serviceMessenger = serviceReplyTo;
Message msg = Message.obtain();
if (socket.isConnected()) {
msg.what = Event.CONNECTED;
} else {
msg.what = Event.DISCONNECTED;
}
messageService(msg);
}
/*
* Support methods
*/
public Looper getLooper() {
return Looper.getMainLooper();
}
public void stopLooper() {
serviceIncomingHandler.getLooper().quit();
}
private void messageService(Message msg) {
try {
serviceMessenger.send(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
private class ServiceToSocketIncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Event.CONNECT:
Log.d("Socket", "Service said CONNECT");
onConnect(msg.replyTo);
break;
case Event.DISCONNECT:
Log.d("Socket", "Service said DISCONNECT");
onDisconnect();
break;
case Event.NEW_PICTURE:
Log.d("Socket", "Service said NEW_PICTURE");
onNewPicture(msg.obj);
break;
default:
Log.e("Socket", "Service said some weird shit...");
super.handleMessage(msg);
}
}
}
}
LogCat输出
Client(451): Binding to Service...
Service(451): TCPSocketService created
Service(451): Started...
Client(451): Binded to service
Service(451): Client said HELLO
Client(451): Service said HELLO
Service(451): Client said START_THREAD
Socket(451): New thread started...
Client(451): Service said THREAD_STARTED
Service(451): Client said CONNECT
是否有完成获取Thread的Incoming Handler目标以便我可以从Service
类向他们发送消息?
提前感谢您的帮助!
答案 0 :(得分:1)
您也可以延长HandlerThread
。
答案 1 :(得分:0)
我设法通过SocketThread
班extend Thread
代替implements Runnable
来实现这一目标。然后,我在类中创建了一个Looper
对象,并在SocketThread
类中创建了一个返回Looper
的方法和一个返回Handler
的方法。这样,TCPSocketService
会创建一个SocketThread
对象,并要求它为Looper
和Handler
,因此它可以开始来回发送消息。