IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android用热点互传文件的坑 -> 正文阅读

[移动开发]Android用热点互传文件的坑

当笔者接到这个需求的时候,下意识的认为,用热点一定可以完成互传。 当然笔者的自信是对的,只是里面有两个坑需要跳过去。

1. 热点问题

问题出在两个android10及以上手机。 面临的情况如下:

1. A手机创建热点, 并且建立一个ServerSocket。B手机连接A手机热点后, 访问A手机的ServerSocket,无法连接上

2. B手机在连接上A手机的热点后,也建立一个ServerSocket。同样,A手机也连接不上B手机的ServerSocket。

3. 不过A手机和B手机分别可以访问自己。

最后是如何解决问题的呢? 发现通过B手机的浏览器无法访问B手机自己,直接给你报网络没有连接的错误提示。可是B手机明明连接了热点。

这个情况给了我提示,想到系统可能偷懒了。因为A手机创建的热点无法访问外网(android 10开始的),所以B手机的网络状态也被标记为了无法访问外网。这让系统认为反正无法访问外网,所以干脆直接躺倒,不去尝试了。

那么强制指定一个网络行不行呢?行的!B手机在连接上A 手机的热点后,再调用一下connectivityManager.bindProcessToNetwork(network)就马上解决问题了。network是热点的网络。

完整代码如下:

    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void connectWifiQ(Activity activity, String ssid, String password, OnWifiConnectCallback onWifiConnectCallback) {
        NetworkSpecifier specifier = null;

        specifier = new WifiNetworkSpecifier.Builder()
                .setSsidPattern(new PatternMatcher(ssid, PatternMatcher.PATTERN_PREFIX))
                .setWpa2Passphrase(password)
                .build();

        NetworkRequest request =
                new NetworkRequest.Builder()
                        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                        .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        .setNetworkSpecifier(specifier)
                        .build();

        ConnectivityManager connectivityManager = (ConnectivityManager)
                mApplicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
                // do success processing here..
                Log.d(TAG, "wifi-connect-succeed");
                try {
                    connectivityManager.bindProcessToNetwork(network);
                } catch (IllegalStateException e) {
                    Log.e(TAG, "ConnectivityManager.NetworkCallback.onAvailable: ", e);
                }

                onWifiConnectCallback.succeed();
              //  connectivityManager.unregisterNetworkCallback(this);
            }

            @Override
            public void onUnavailable() {
                // do failure processing here..
                Log.d(TAG, "wifi-connect-failed");
                onWifiConnectCallback.failed();
            }
        };

        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                connectivityManager.requestNetwork(request, networkCallback);
            }
        });
    }

onAvailable会回调好几次,想通过connectivityManager.unregisterNetworkCallback(this)使得只回调一次,那是不行的,会失效。你只能在自己的回调里去过滤。

2. getHostName()耗时问题

解决了热点问题后,B手机就可以访问A手机了。A手机也可以访问B手机了,但是网络速度超慢,一个普通请求要10秒左右才返回。C手机也连上A手机的热点,并创建ServerSocket。 B手机和C手机之间的网络速度一样奇慢无比。这就又奇怪了,明显又与常识不符。

原因分析思路如下:

这个问题可能是两种情况导致:

1. B手机真没有接到A手机的请求。

2. B手机接到A手机请求了,但是接到后,由于某些原因卡住了。

3. 每次都是10秒,挺可疑的。

如果是第一个原因,那就比较棘手了。可是该死的,下意识的认为是第一个原因导致的,由此浪费了不少时间。可能对第三方http server库太信任了,一直没去想是第二个原因引起的。后来才想到 是因为每次都是10秒,很可疑。

最后调试了一下,问题果然出在socket accept后, 调用了getHostName()?这个方法耗时特别长!

getHostName()调用的性能取决于JVM和目标主机的域名服务器之间的网络/技术堆栈的性能。可哪有什么host name, 都是IP地址直接访问的。问题就在于DNS的反向解析, 如果解析不成功, 它会一直尝试, 大概10秒的时间, 所以这10秒是阻塞的。

解决方案,就是删除这个方法的调用。 因为局域网里的通信,根本不需要知道对方的host name,也没有。 知道对方IP地址就好了。

这两个坑,现在看看是不大。但是在于分析的思路很重要。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 12:12:20  更:2021-08-07 12:14:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 12:32:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码