Android - 向线程传入处理程序发送消息

时间:2014-01-21 16:21:49

标签: java android multithreading android-service

我有Service启动处理网络活动的新Thread。我将ActivityServiceThread全部放在不同的文件中。我正在尝试使用通过传递Messenger扩展Messenger而创建的Handler来设置它们之间的通信。我已经弄清楚如何让ServiceActivity很好地交谈,但是我无法弄清楚如何给我的Service目标以允许它发送消息单独的Thread

这就是我现在正在尝试的内容,但是ServiceThread的邮件永远不会发送...

服务

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类向他们发送消息?

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您也可以延长HandlerThread

答案 1 :(得分:0)

我设法通过SocketThreadextend Thread代替implements Runnable来实现这一目标。然后,我在类中创建了一个Looper对象,并在SocketThread类中创建了一个返回Looper的方法和一个返回Handler的方法。这样,TCPSocketService会创建一个SocketThread对象,并要求它为LooperHandler,因此它可以开始来回发送消息。