守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 1185|回复: 0

[Android] 在ANE中连接Socket服务器的注意事项

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51792
    钢镚
    1422

    开源英雄守望者

    发表于 2015-4-27 15:17:33 | 显示全部楼层 |阅读模式
    本帖最后由 破晓 于 2015-4-27 15:22 编辑

    前戏
    也许你会奇怪,既然AS提供了Socket实现,为什么还要用ANE来实现Socket连接?
    在ANE插件中启动AIR开发的Android应用一文的最后,我提到了一个应用案例,我现在将这个案例明确的说明一下。
    对于游戏开发者来说,我们希望能推送给用户一些消息。如果使用常规的手段,只能在用户打开游戏的时候,才能和服务器通信,收到这些消息。
    如果用户几天不上线,那么可能会错过这些消息,导致游戏中的公告、奖励不能及时到达。
    要解决这个问题,我们可以在Android系统中注册一个Service。这个Service长期保持与服务器的连接,或者隔段时间连接一次服务器,收到消息后马上推送给用户。
    这种Service,使用AIR是无法实现的,必须用ANE来解决。因此,我们不可能使用AS的Socket来连接服务器,必须用Android SDK提供的Socket连接方法。

    阻力
    在JAVA中实现Socket客户端的方法很简单,这里提供一些简单(且不完整)的代码:
    1. private void connectSocket() throws UnknownHostException, IOException
    2. {
    3.     Socket __socket = new Socket();
    4.     //超时10秒
    5.     __socket.connect(new InetSocketAddress(\"192.168.18.30\", 30000), 10000);
    6.     InputStream __input = __socket.getInputStream();
    7.     OutputStream __output = __socket.getOutputStream();
    8.     if(__socket.isConnected()) Log.i(TAG, \"连接成功\");
    9.     byte[] __sendByte = getSenderData();
    10.     Log.i(TAG, \"发送数据的长度:\"+__sendByte.length);
    11.     __output.write(__sendByte);
    12.     while(true)
    13.     {
    14.         if(__input.available()>0)
    15.         {
    16.             byte[] __bytes = new byte[__input.available()];
    17.             __input.read(__bytes);
    18.             Log.i(TAG, \"收到的数据长度:\"+__bytes.length);
    19.             break;
    20.         }
    21.     }
    22.     Log.i(TAG, \"关于连接\");
    23.     __socket.close();
    24. }
    复制代码
    上面的代码是阻塞式的,没有使用nio是因为我觉得ANE本来就运行在单独的线程中,不用考虑阻塞对UI的影响。上面的代码在3台Android 2.3设备上运行良好。
    但当我在Android 4.0设备上测试的时候,问题出现了。
    在连接Socket服务器的时候,ANE进程会崩溃并报错,虽然它不影响AIR主进程,但用户可以看到Android系统推送的错误提示。
    我测试了3台Android 4.0设备,其中包括2部手机和一部平板电脑,均有同样的问题出现。
    高潮

    为什么会如此?从stackoverflow上找到的说法是,从Honeycomb(蜂巢,Android 3.0)开始,Andorid就不允许在主进程中进行网络IO的调用。
    应该使用后台线程或者非阻塞式的API来进行网络通信。如果强插,Android会抛出NetworkOnMainThreadException异常。
    于是,我把connectServer方法丢到一个线程中去执行,在3台Android 4.0设备上,测试全部正常。
    1. try
    2. {
    3.     Thread __socketThread = new Thread(
    4.             new Runnable()
    5.             {
    6.                
    7.                 @Override
    8.                 public void run()
    9.                 {
    10.                     try
    11.                     {
    12.                         connectServer();
    13.                     }
    14.                     catch(Exception $e)
    15.                     {
    16.                         Log.e(TAG, $e.getMessage());
    17.                     }
    18.                     
    19.                 }
    20.             }
    21.             );
    22.     __socketThread.start();
    23. }
    24. catch (Exception e)
    25. {
    26.     Log.e(TAG, e.getMessage());
    27. }
    复制代码
    尾声

    虽然问题解决了,但疑问依然存在。
    疑问1

    ANE线程难道不就是后台线程么?本身ANE是没有可视界面的,与UI也无关,应该符合上面的条件啊。
    疑问2

    我随后使用Android SDK(非AIR)开发了一个应用,就在主UI进程中使用阻塞式IO访问Socket服务器,且在Android 4.0系统上测试,却没有发现任何问题。所有的网络通信都正常。谁能解答这两个问题么?




    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2019-11-23 01:55 , Processed in 0.045315 second(s), 37 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表