V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
atfeel
V2EX  ›  Android

Android 如何通过 Socket 高效率发送 int 数组?

  •  
  •   atfeel · 2020-05-20 09:54:18 +08:00 · 5410 次点击
    这是一个创建于 1408 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我同一台手机两个 APP,A 和 B,他们通过 SOCKET 通信,A 是客服端,B 是服务端

    A 要发送一个长度为 90,0000 的 int[] 给 B

    SOCKET 不能直接发送 int[],要转成 byte[]才能发送。

    由于数据量大,把长度为 90,0000 的 int[]转成 byte[]大概要 35ms

    由于特殊原因我不想浪费这 35ms 。

    另外,B 端因为最终需要使用的是 int[],A 把 int[]转成 byte[]再发送

    B 接收到 byte[]还得转回 int[],也是需要 35ms

    等于白白浪费了 70ms 。

    有没有什么办法,能让 B 快速获取到 A 的 int[]呢?

    也不是非得用 SOCKET 不可,只要能让 B 快速获取到 A 的 int[]就行了

    A 的 int[]是不固定的

    各位 V 友有办法吗?

    24 条回复    2020-05-29 09:43:00 +08:00
    wellwell
        1
    wellwell  
       2020-05-20 10:00:56 +08:00
    蛤 还能不用 socket 通信的办法?
    GM
        2
    GM  
       2020-05-20 10:03:51 +08:00
    @wellwell 可以保存到文件,然后用 U 盘复制到另一台手机上加载就好啦!
    hyperion1
        3
    hyperion1  
       2020-05-20 10:04:56 +08:00 via iPhone
    共享内存
    optional
        4
    optional  
       2020-05-20 10:05:29 +08:00 via Android
    压缩一下,如果你的 int 高位很多 0,转成 byte 之后压缩空间巨大
    pursuer
        5
    pursuer  
       2020-05-20 10:12:03 +08:00 via Android
    bytebuffer 设置小端字节序试试
    islxyqwe
        6
    islxyqwe  
       2020-05-20 10:13:09 +08:00
    按流发啊,一边转换一边发,而不是一次全转了,等转完再发。找找对应的 API 吧
    Kamiyu0087
        7
    Kamiyu0087  
       2020-05-20 10:22:43 +08:00
    int[] 内的值都是在 byte 范围内的还是有有超过一个 byte 大小的?
    如果有超过一个 byte 大小的,那只能先转 byte[] 啊
    windplume
        8
    windplume  
       2020-05-20 10:30:25 +08:00
    共享内存
    Rheinmetal
        9
    Rheinmetal  
       2020-05-20 10:30:48 +08:00
    同一台手机的话倒是可以 不过不能用 socket 了 不清楚性能如何 应该快一点把
    https://devarea.com/android-creating-shared-memory-using-ashmem/
    atfeel
        10
    atfeel  
    OP
       2020-05-20 10:35:00 +08:00
    @Kamiyu0087 int[]里面保存的是图片的颜色,A 通过

    int[] rgbdata = new int[screenWidth * screenHeight];
    bitmap.getPixels(rgbdata, 0, screenWidth, 0, 0, screenWidth, screenHeight);

    取到的
    atfeel
        11
    atfeel  
    OP
       2020-05-20 10:36:42 +08:00
    @windplume 共享内存没试过,有具体点的介绍吗
    resist
        12
    resist  
       2020-05-20 10:39:56 +08:00
    难道不是转换一点发一点吗?
    atfeel
        13
    atfeel  
    OP
       2020-05-20 10:48:02 +08:00
    @windplume 内存共享是指 MemoryFile ?这个方法,还是要将 intt[]转成 byte[]才行,这个还是避免不了 浪费 70ms 的时间
    atfeel
        14
    atfeel  
    OP
       2020-05-20 10:49:51 +08:00
    @resist 现在不是发的问题,socket 发 90,0000 的长度,在本地是很快的,但是我要发的是 int[],把它转成 byte[]费时,接收端还要还原成 int[]
    movistar
        15
    movistar  
       2020-05-20 10:50:55 +08:00 via iPhone
    如果你确定耗时是在 int 转 byte 这个流程里
    而不是创建 byte 数组的流程里
    那是有解决方案的
    通过 unsafe 获取到数组的指针,然后根据长度直接把整段数据 copy 到 byte 数组里面即可,可以不转换就是整块 copy 。
    可以节省转换的时间。但是创建数组的开销还是有的,还有一次 copy 开销。
    xiangyuecn
        16
    xiangyuecn  
       2020-05-20 10:55:09 +08:00
    负优化? 4 字节*900_000≈3M 数据量,你折腾这几十毫秒,还不如用 gzip 压缩一下,压到 1M,网络传输节省的时间瞬间少 2/3
    tanranran
        17
    tanranran  
       2020-05-20 11:02:15 +08:00
    Cap'n Proto ?
    guchengyehai1
        18
    guchengyehai1  
       2020-05-20 13:11:00 +08:00 via Android
    getPixels 获取到的颜色信息是存在一块内存中,Bitmap 里面应该有指针信息,你可以把这块内存东西用共享内存传输,参照 Linux mmap API
    aguesuka
        19
    aguesuka  
       2020-05-20 13:12:10 +08:00 via Android
    不要使用数组,自定义一个 IntArray 接口,实现 get(int) set(int, int)操作。用 ByteBuffer 作为实现
    imkujio
        20
    imkujio  
       2020-05-20 15:02:07 +08:00
    我能想到的两种解决思路:
    1.数据优化,使用其他体积更小处理速度更快的形式存储。可以在 S 端数据边产生边转换。
    2.分段传输,将数据拆分,具体看 A 端对数据的处理顺序合理进行分段,边传输边转换
    miaoxia
        21
    miaoxia  
       2020-05-20 16:13:52 +08:00
    1. AIDL 直接传 int[]
    2. 分包传
    ruixianxx
        22
    ruixianxx  
       2020-05-20 16:24:28 +08:00
    @miaoxia AIDL 正解
    atfeel
        23
    atfeel  
    OP
       2020-05-23 21:31:12 +08:00
    @miaoxia 感谢靠谱
    LLaMA2
        24
    LLaMA2  
       2020-05-29 09:43:00 +08:00
    我有个疑惑,int -> byte 难道不会有精度丢失?
    楼上有很多套路都是好套路,
    想简单点就用文件,两边同时操作,一边只读一边只写。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1889 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 16:26 · PVG 00:26 · LAX 09:26 · JFK 12:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.