3

I'm trying to develop an Android application which is going to use Netty.

First of all I want to test Netty on Android, so I'm going to develop EchoClient example.

I'm "translating" client part. This part has two classes: EchoClient and EchoClientHandler

EchoClient is run as a thread, and EchoClientHandler handles all network stuff.

On main method, EchoClient is run like this:

new EchoClient(host, port, firstMessageSize).run();

EchoClientHandler uses an asynchronous event programming model.

Here is a piece of code of EchoClient:

public void run() {
    // Configure the client.
    ClientBootstrap bootstrap = new ClientBootstrap(
            new NioClientSocketChannelFactory(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool()));

    // Set up the pipeline factory.
    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() throws Exception {
            return Channels.pipeline(
                    new EchoClientHandler(firstMessageSize));
        }
    });

    // Start the connection attempt.
    ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));

    // Wait until the connection is closed or the connection attempt fails.
    future.getChannel().getCloseFuture().awaitUninterruptibly();

    // Shut down thread pools to exit.
    bootstrap.releaseExternalResources();
}

This run() method could be AsyncTask.doBackground() method.

As you can see EchoClientHandler is part of this class.

And this is EchoClientHandler method which I want to use in UI Thread:

@Override
public void messageReceived(
        ChannelHandlerContext ctx, MessageEvent e) {
    // Send back the received message to the remote peer.
    transferredBytes.addAndGet(((ChannelBuffer) e.getMessage()).readableBytes());
    e.getChannel().write(e.getMessage());
}

How can I do to use EchoClientHandler in an AsynTask? I don't know how to update a TextView on onProgressUpdate when messageReceived is invoked.

Any advice?

VansFannel
  • 45,055
  • 107
  • 359
  • 626

1 Answers1

0

Maybe you can use a callback.

Step 1. Define an interface

public interface MyCallback {
     public void onMessage(string msg);
}

Step 2. Take an object conforming to that interface in EchoHandler constructor and store it as a class variable

private MyCallback _myCallback
public EchoClientHandler(int firstMessageSize, MyCallback callback) {
   _myCallback = myCallback;
   ...
}

Step 3. Pass an object to that constructor in the pipeline. myCallback can come from run() as a parameter or in your EchoClient constructor.

// Set up the pipeline factory.
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
    public ChannelPipeline getPipeline() throws Exception {
        return Channels.pipeline(
                new EchoClientHandler(firstMessageSize, myCallback));
    }
})

Step 4. Invoke call back in your message handler

@Override
public void messageReceived(
    ChannelHandlerContext ctx, MessageEvent e) {
    // Send back the received message to the remote peer.
    transferredBytes.addAndGet(((ChannelBuffer) e.getMessage()).readableBytes());
    e.getChannel().write(e.getMessage());

    _myCallback.onMessage("message");
}

Hope this helps.

Veebs
  • 2,390
  • 13
  • 10