• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > 在 Android 上使用 RxNetty

在 Android 上使用 RxNetty

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了rxnetty,android sqlite使用,android dialog使用,android okhttp使用,android eventbus使用等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

在 Android 上使用 RxNetty


在 Android 上使用 RxNetty

Netty是由JBOSS提供的一个Java开源框架,是一个支持TCP/UDP/HTTP等网络协议的通信框架,和Mina类似,广泛应用于RPC框架。RxNetty则是支持RxJava的Netty开源框架,现在我们来看一下在Android上如何使用RxNetty。

添加RxNetty

在 Android Studio 中添加 RxNetty 的依赖:
这里写图片描述
把RxNetty的tcp包加入到依赖,直接这样编译会有两个问题,第一个问题是jar重复:

com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK THIRD-PARTY
File1: C:\Users\XXX.gradle\caches\modules-2\files-2.1\org.openjdk.jmh\jmh-core\1.11.2\f4f8cd9874f5cdbc272b715a381c57e65f67ddf2\jmh-core-1.11.2.jar
File2: C:\Users\XXX.gradle\caches\modules-2\files-2.1\org.openjdk.jmh\jmh-generator-annprocess\1.11.2\72d854bf76ba5e59596d4c887a6de48e7003bee2\jmh-generator-annprocess-1.11.2.jar

解决办法:

dependencies {
  ...
  compile('io.reactivex:rxnetty-tcp:0.5.2-RC1') {
    exclude group: 'org.openjdk.jmh'
  }
  ...
}

另一个问题是引用的netty包中META-INF/下的部分文件重复。
解决办法:

  packagingOptions {
    ...
    exclude 'META-INF/INDEX.LIST'
    exclude 'META-INF/BenchmarkList'
    exclude 'META-INF/io.netty.versions.properties'
    exclude 'META-INF/CompilerHints'
    ...
  }

到这里RxNetty就成功添加到项目模块中了。接下来看看到底如何使用RxNetty。

如何使用

拿TCP协议举例,用过Netty的都清楚创建连接的步骤:

        workerGroup = new NioEventLoopGroup();
        Bootstrap boot = new Bootstrap();
        boot.group(workerGroup)
            .channel(NioSocketChannel.class)
            .option(ChannelOption.TCP_NODELAY, true)
            .handler(new ChannelInitializer() {
              @Override public void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline p = ch.pipeline();
                p.addLast("decoder", new MessageDecoder());
                p.addLast("encoder", new MessageEncoder());
                p.addLast("handler", new MessageHandler());
              }
            });
        ChannelFuture f =
            boot.connect("localhost", 8888).syncUninterruptibly();
        channel = f.channel();

自定义的协议需要我们自己实现编码解码Handler,还有最后处理数据的MessageHandler:

@Sharable
public class MessageHandler extends SimpleChannelInboundHandler {
    @Override
    public void messageReceived(ChannelHandlerContext ctx, Message msg)
            throws Exception {
            //处理消息
    }
}

在RxNetty中可以不实现MessageHandler,因为通过注册的观察者可以得到最终解码后的协议对象。
下面是RxNetty创建连接的方法:

  Connection mConnection;

  public Observable connect(final String url, final int port) {
    return Observable.create(new Observable.OnSubscribe() {
      @Override public void call(final Subscriber subscriber) {
        TcpClient.newClient(url, port).addChannelHandlerLast("decoder",
            new Func0() {
              @Override public ChannelHandler call() {
                return new StringDecoder();
              }
            }).addChannelHandlerLast("encoder", new Func0() {
          @Override public ChannelHandler call() {
            return new StringEncoder();
          }
        }).createConnectionRequest().subscribe(new Observer>() {
          @Override public void onCompleted() {
            subscriber.onCompleted();
          }

          @Override public void onError(Throwable e) {
            subscriber.onError(e);
          }

          @Override public void onNext(Connection connection) {
            mConnection = connection;
            subscriber.onNext(true);
          }
        });
      }
    });
  }

上面的TCP客户端创建了一个字符串解码器、一个字符串编码器,然后创建链接,在链接创建成功后把链接对象connection保存到mConnection方便后面发送数据,同时通知订阅者socket连接成功。

在Android中不能在UI线程创建网络链接,就连InetSocketAddress类都不能在UI线程中创建,TcpClient.newClient(url, port)...createConnectionRequest()本身是一个Observable,但是由于方法newClient(url, port)中创建了InetSocketAddress类,Android严苛模式会报异常,所以上面创建链接的TcpClient方法在外层又包裹了一个Observable,让它运行在IO线程等其它非UI线程才可以正常创建socket链接。

用来接收数据、发送数据的方法同样返回一个Observable,代码如下:

  public Observable receive() {
    if (mConnection != null) {
      return mConnection.getInput();
    }
    return null;
  }

  public Observable send(String s) {
    return mConnection.writeString(Observable.just(s));
  }

测试上面方法的客户端代码:

  public void rxNettyClientTest() {
    connect("localhost", 60000).subscribe(new Observer() {
      @Override public void onCompleted() {

      }

      @Override public void onError(Throwable e) {
        //reconnect
        Observable.timer(1, TimeUnit.SECONDS).subscribe(new Action1() {
          @Override public void call(Long aLong) {
            if (mConnection != null) mConnection.closeNow();
            rxNettyClientTest();
          }
        });
        System.out.println("reconnect");
      }

      @Override public void onNext(Boolean aBoolean) {
        //send data
        send("hello world!").subscribe(new Action1() {
          @Override public void call(Void aVoid) {
            System.out.println("send success!");
          }
        });
        //receive data
        receive().subscribe(new Observer() {
          @Override public void onCompleted() {

          }

          @Override public void onError(Throwable e) {
            //reconnect
            Observable.timer(1, TimeUnit.SECONDS).subscribe(new Action1() {
              @Override public void call(Long aLong) {
                if (mConnection != null) mConnection.closeNow();
                rxNettyClientTest();
              }
            });
            System.out.println("reconnect");
          }

          @Override public void onNext(String s) {
            System.out.println("receive:" + s);
          }
        });
      }
    });
  }

上面的代码包涵了读、写数据和重连等主要功能。
然后是创建服务端的代码:

  public void rxNettyServerTest() {
    TcpServer server;
    server = TcpServer.newServer(60000).addChannelHandlerLast("string-decoder",
        new Func0() {
          @Override public ChannelHandler call() {
            return new StringDecoder();
          }
        }).addChannelHandlerLast("s



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 在 Android 上使用 RxNetty

相关文章

  • 2017-05-26andriod CheckBox,andriodcheckbox
  • 2017-05-26Android 关于“NetworkOnMainThreadException”,networkonmainthread
  • 2017-05-26PostgreSql数据库的神器 FDW
  • 2017-05-26perf profiling 分析程序性能
  • 2017-05-26深入理解Activity启动流程
  • 2017-05-26Android开发文档翻译之-Services
  • 2017-05-26Unity编译时找不到AndroidSDK的问题 | Unable to list target platforms(转载),unityengine.ui找不到
  • 2017-05-26在 Android 上使用 RxNetty
  • 2017-05-26kvm性能优化
  • 2017-05-26Android studio 插件安装 plugin

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 安卓开源项目周报0405,安卓开源项目0405
    • 微信小程序监控,信小程序监控
    • 自定义加载loading view动画组件的使用。,loadingview
    • Android 之 Intent(意图),androidintent意图
    • Android小知识,理财小知识
    • Toast显示图文界面——Android开发之路1,toastandroid
    • Gradle Android客户端程序打包,gradleandroid
    • Android 系统版本&API对照表,android系统版本
    • Android 学习1----控件的学习,android1----
    • moveTaskToback退后台的用法及作用,movetasktoback后台

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有