首页 > 解决方案 > 在android studio中,当手机没有互联网时,如何防止缓冲阅读器从url读取错误

问题描述

在我的应用程序中,当我按下按钮时,缓冲阅读器应该从在线文本文件中读取一行文本。

作为测试,如果文本被正确阅读,我希望出现“成功”的祝酒词。如果读取失败,例如因为手机没有连接到互联网,我希望出现“失败”的祝酒词。

但是,如果我打开飞行模式,然后按下按钮,它似乎永远“挂起”,“失败”的 toast 永远不会出现——或者它只是让应用程序完全崩溃。

这是我正在使用的代码:

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            new NotePadFileFromServer().execute();
        }
    });

public class NotePadFileFromServer extends AsyncTask<Void, Void, Void>{

    @Override
    protected Void doInBackground(Void... params) {
        try {
            url = new URL(TextFileURL);
            bufferReader = new BufferedReader(new InputStreamReader(url.openStream()));
            TextHolder = bufferReader.readLine();
            bufferReader.close();
        } catch (Exception e) {
            Toast.makeText(MainActivity.this, "Fail!", Toast.LENGTH_SHORT).show();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void finalTextHolder) {
        Toast.makeText(MainActivity.this, "Success!", Toast.LENGTH_SHORT).show();
        super.onPostExecute(finalTextHolder);
    }

}

我尝试使用 ConnectivityManager 添加预检查以测试是否有按照以下代码的 Internet 连接:https ://stackoverflow.com/a/58146646/4250107 ,但这仅适用于电话用户已专门关闭互联网,如果打开wifi功能,再次发生崩溃,但没有互联网。然后我尝试按照以下代码检查互联网连接:https://stackoverflow.com/a/58146896/4250107,但这也会使应用程序崩溃,因为显然(?)尝试 ping 服务器在三星手机上不起作用.

编辑:最终固定代码。

public class NotePadFileFromServer extends AsyncTask<Void, Void, String>{

    @Override
    protected String doInBackground(Void... params) {
        try {
            URLConnection url = new URL(TextFileURL).openConnection());
            url.setConnectTimeout(1000);
            url.setReadTimeout(1000);
            bufferReader = new BufferedReader(new InputStreamReader(url.getInputStream()));
            TextHolder = bufferReader.readLine();
            bufferReader.close();
            return "Success!";
        } catch (Exception e) {
            return "Fail!";
        }
    }

    @Override
    protected void onPostExecute(String success) {
        Toast.makeText(MainActivity.this, success, Toast.LENGTH_SHORT).show();
        super.onPostExecute(success);
    }
}

标签: javaandroidandroid-studio

解决方案


是的,正如您所说,ConnectivityManager 不会帮助您,因为如果您有 wifi 但没有互联网,它会崩溃。

但是,可以检查互联网连接。我不能用 ping 来做(和你一样),但是当我尝试打开一些打开的端口(80 或 443)的套接字时我可以做到。这是使用 rxjava 的代码,但您可以将其调整为您正在使用的代码。

fun isOnline(context: Context?): Single<Boolean> {
return Single.fromCallable {
    try {
        // Connect to Google DNS to check for connection
        val timeoutMs = 2500
        val socket = Socket()
        val address = InetAddress.getByName("www.google.com")

        val socketAddress = InetSocketAddress(address, 443)

        socket.connect(socketAddress, timeoutMs)
        socket.close()

        true
    } catch (e: Exception) {
        false
    }
}.subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
}

就我而言,我用后端打开了套接字,所以我也可以检查它是否正常工作。我把 www.google.com 放在你没有后端的情况下。

使用方法是:

isOnline(context).subscribe { hasInternet -> 
    //Conditional check
} 

推荐阅读