[Android初级]android与netty4初体验
16lz
2021-01-25
博主曾经对netty4的helloword很感兴趣,也曾单纯的写过一个小小的聊天室java代码,现在重新来看看,浏览了这位牛人的博客点击去看看
我觉得受益匪浅,故拿来分享。
这次是在android上使用netty作为客户端,来与服务端相互通讯的小事例,纯粹的helloworld,效果就是在android程序中发送一个消息到服务端,然后服务端也回一个消息给客户端,很简单的demo,.大牛看了可不要吐槽啊!
1.demo结构
2.服务端代码:
Server.java
package org.jan.netty.demo;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;public class MyHelloServer {private static final int PORT = 7878;public static void main(String[] args) {EventLoopGroup parentGroup = new NioEventLoopGroup();EventLoopGroup childrenGroup = new NioEventLoopGroup();try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(parentGroup, childrenGroup);serverBootstrap.channel(NioServerSocketChannel.class);//添加工作线程serverBootstrap.childHandler(new MyHelloServerInitializer());// 服务器绑定端口监听ChannelFuture cf = serverBootstrap.bind(PORT).sync();// 监听服务器关闭监听cf.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {parentGroup.shutdownGracefully();childrenGroup.shutdownGracefully();}}}
MyHelloServerHandler.java
package org.jan.netty.demo;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import java.net.InetAddress;import java.nio.charset.Charset;public class MyHelloServerHanler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg)throws Exception {String recStr = new String(msg.getBytes(), Charset.forName("UTF-8"));//收到消息直接打印输出System.out.println(ctx.channel().remoteAddress()+" say :"+recStr);//返回客户端 ctx.writeAndFlush("Received your message!\n");}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("RamoteAddress: "+ctx.channel().remoteAddress()+" active!");//ctx.writeAndFlush("Welcome to " + InetAddress.getLocalHost().getHostName() + "'s service!\n");ctx.writeAndFlush("我是服务端,我是服务端!\n");super.channelActive(ctx);}}
3.android客户端代码:
/** * demo主界面:只有一个按钮发送消息 * @author jan */public class ClientActivity extends Activity {private static final String TAG = "MainActivity";private static Context context;public static int MSG_REC=0xabc;public static int PORT = 7878;public static final String HOST = "192.168.50.110";private NioEventLoopGroup group;private Button sendButton;private Channel mChannel;private ChannelFuture cf;private Handler mHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {if(msg.what==MSG_REC){Toast.makeText(context, msg.obj.toString(), 1000).show();}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);context = this;connected();sendButton = (Button) findViewById(R.id.netty_send_button);sendButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {sendMessage();}});}// 连接到Socket服务端private void connected() {new Thread() {@Overridepublic void run() {group = new NioEventLoopGroup();try {// Client服务启动器 3.x的ClientBootstrap// 改为Bootstrap,且构造函数变化很大,这里用无参构造。Bootstrap bootstrap = new Bootstrap();// 指定EventLoopGroupbootstrap.group(group);// 指定channel类型bootstrap.channel(NioSocketChannel.class);// 指定Handlerbootstrap.handler(new MyClientInitializer(context,mHandler));bootstrap.option(ChannelOption.SO_KEEPALIVE, true);bootstrap.option(ChannelOption.TCP_NODELAY, true);bootstrap.option(ChannelOption.SO_TIMEOUT, 5000);// 连接到本地的7878端口的服务端cf = bootstrap.connect(new InetSocketAddress(HOST, PORT));mChannel = cf.sync().channel();} catch (Exception e) {e.printStackTrace();}}}.start();}//发送数据private void sendMessage() {mHandler.post(new Runnable() {@Overridepublic void run() {try {Log.i(TAG, "mChannel.write sth & " + mChannel.isOpen());mChannel.writeAndFlush("hello,this message is from client.\r\n");mChannel.read();} catch (Exception e) {e.printStackTrace();}}});}@Overrideprotected void onDestroy() {super.onDestroy();if (group != null) {group.shutdownGracefully();}}}
4.客户端中 bootstrap的初始化类MyClientInitializer.java
public class MyClientInitializer extends ChannelInitializer<SocketChannel> {private Context context;private Handler handler;public MyClientInitializer(Context ctx,Handler handler){this.context = ctx;this.handler = handler;}@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();/** * 这个地方的必须和服务端对应上。否则无法正常解码和编码 */pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));//客户端的逻辑pipeline.addLast("handler",new MyClientHandler(context,handler));}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {System.out.println("---channelRead--- msg="+msg);super.channelRead(ctx, msg);}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {System.out.println("---channelReadComplete---");super.channelReadComplete(ctx);}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {Log.i("MyClientInitializer","---channelActive---");super.channelActive(ctx);}}5.对应的数据处理类 ,没有什么新鲜性的东西哦。MyClientHandler.java
public class MyClientHandler extends SimpleChannelInboundHandler<String> {private Context ctx;private Handler handler;public MyClientHandler(Context context, Handler handler) {this.ctx = context;this.handler = handler;}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg)throws Exception {Log.d("MyHelloClientHandler", "channelRead0->msg="+msg);Message m = new Message();m.what = ClientActivity.MSG_REC;m.obj = msg;handler.sendMessage(m);}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("Client active");super.channelActive(ctx);}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {System.out.println("Client close ");super.channelInactive(ctx);}}
实现效果:
去下载demo
更多相关文章
- Nginx系列教程(二)| 一文带你读懂Nginx的正向与反向代理
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Android(安卓)== 简单的binder通信
- Android通信方式篇(一)-消息机制(Java层)
- Android入门进阶教程(16)-ActivityThead、ActivityManagerServic
- Android(安卓)开发之旅:短信的收发及在android模拟器之间实践(二)
- 第三方推送已死
- Android(安卓)6.0 SSL通信
- Handler消息处理机制