如何处理网络问题

时间:2023-01-31 03:28:59

One of my apps uses a lot of HTTP requests to communicate with its back-end. I use 2 different implementations to perform these requests:

我的一个应用程序使用大量HTTP请求与其后端进行通信。我使用2种不同的实现来执行这些请求:

  • The library Volley for most cases
  • 大多数情况下的图书馆Volley
  • A combination of AsyncTask and DefaultHttpClient for few cases
  • 几种情况下AsyncTask和DefaultHttpClient的组合

Most of the time, everything works well. But sometimes I have a bunch of network exceptions raised and shown into Crashlytics:

大多数时候,一切都运作良好。但有时我会提出一系列网络异常并将其显示在Crashlytics中:

  • java.net.UnknownHostException: Unable to resolve host "mydomain.com": No address associated with hostname Caused by: libcore.io.GaiException: getaddrinfo failed: EAI_NODATA (No address associated with hostname)

    java.net.UnknownHostException:无法解析主机“mydomain.com”:没有与主机名关联的地址引起:libcore.io.GaiException:getaddrinfo failed:EAI_NODATA(没有与主机名关联的地址)

  • com.android.volley.ServerError at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:175) at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:110)

    来自com.android.volley.NetworkDispatcher.run的com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:175)中的com.android.volley.ServerError(NetworkDispatcher.java:110)

With a bit of research, I found that this is supposed to happen when the device has a really bad 3g/4g or behind a VPN/subnetwork so it can't reach my website.

通过一些研究,我发现这应该发生在设备有一个非常糟糕的3g / 4g或在VPN /子网后面,所以它无法到达我的网站。

How do I make sure the device is really connected to internet? I actually perform these requests only if this function return true:

如何确保设备真正连接到互联网?我实际上只有在此函数返回true时才执行这些请求:

public static boolean isOnline(Context ctx) {
        ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting()) {
            return true;
        }
        return false;
}

Or should I just let it go and assume it is normal to get up to few hundreds of these warning per month?

或者我应该放手,并假设每月达到几百个这样的警告是正常的?

3 个解决方案

#1


0  

In order to see if you have internet you have to do something more than check if you have a network connection. Because if your connected to a slow network, captive portal or a VPN you have a connection to the network but no actual internet or usable internet.

为了查看您是否有互联网,您必须做的不仅仅是检查您是否有网络连接。因为如果您连接到慢速网络,强制网络门户或VPN,您可以连接到网络,但没有实际的互联网或可用的互联网。

That's why you still need to check if you have internet/usable internet before you make a HTTP request by adding a simple ping to a server or Google (Because Google is up 99,99% of the time). You can also do it periodically or when you catch the first exception, that's up to you.

这就是为什么你仍然需要在发出HTTP请求之前检查你是否有互联网/可用的互联网,方法是向服务器或谷歌添加一个简单的ping(因为谷歌有99,99%的时间用户)。你也可以定期或当你发现第一个例外时,这取决于你。

public Boolean isInternet() {
    try {       
        Process process = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");      
        int returnVal = process.waitFor();      
        boolean reachable = (returnVal==0);
        return reachable
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return false; 
}

You can also use another method but the general idea is the same use something you know is almost always online and check if you can reach it.

您也可以使用其他方法,但一般的想法是相同的使用,你知道几乎总是在线,并检查你是否可以达到它。

However keep handling exceptions, because there is no way to always catch it and having a back up way of handling things can't hurt

但是要保持处理异常,因为没有办法总是抓住它并且有一个备份方式来处理事情不会受到伤害

#2


0  

How do I make sure the device is really connected to internet?

如何确保设备真正连接到互联网?

You have found out. That's what the errors are telling you.

你发现了。这就是错误告诉你的。

How do I make sure the device is really connected to internet? I actually perform these requests only if this function return true:

如何确保设备真正连接到互联网?我实际上只有在此函数返回true时才执行这些请求:

I'm not in favour of this sort of thing:

我并不赞成这种事:

  • if it tests exactly the same things as the actual request does, it is (i) duplicated work and (ii) not done at the same time
  • 如果它测试与实际请求完全相同的事情,则是(i)重复工作和(ii)不同时完成
  • if it doesn't test exactly the same things as the actual request, you are likely to get both false positives and false negatives
  • 如果它没有测试与实际请求完全相同的东西,那么你可能会得到误报和漏报
  • in all cases, it's an attempt to predict the future. It might fail now and the request succeed, or succeed now and the request fail.
  • 在所有情况下,它都是为了预测未来。它现在可能会失败并且请求成功,或者现在成功并且请求失败。
  • you have to write the error handling code for the request anyway.
  • 你必须为请求编写错误处理代码。

In general the best way to test whether any resource is available is just to try to use it in the normal way, and deal with any adverse consequences as and when they arise.

一般来说,测试任何资源是否可用的最佳方法是尝试以正常方式使用它,并在它们出现时处理任何不利后果。

Or should I just let it go and assume it is normal to get up to few hundreds of these warning per month?

或者我应该放手,并假设每月达到几百个这样的警告是正常的?

I wouldn't say ServerError is normal. It's possible that the server managed to send that to you over a fully functioning network, so it may be a server or client bug you need to investigate. Network outages on the other hand are 'normal' in any topology and technology.

我不会说ServerError是正常的。服务器可能设法通过功能完备的网络将其发送给您,因此可能是您需要调查的服务器或客户端错误。另一方面,网络中断在任何拓扑和技术中都是“正常的”。

#3


-1  

Yes you should check internet availability before making an HTTP request, it saves a lot for you.

是的,您应该在发出HTTP请求之前检查互联网可用性,这为您节省了很多。

The code you should is very good and far better than "pinging" any domain.

您应该使用的代码非常好,并且比“ping”任何域都要好得多。

But still in your case your condition isn't going to be sufficient, because the adapter is actually connected but you may not be able to connect to your server due to poor connection.

但仍然在你的情况下你的条件是不够的,因为适配器实际上是连接的,但由于连接不良,你可能无法连接到你的服务器。

So you should still handle time-out and IO exceptions that might happen while you're executing your requests.

因此,您仍应处理执行请求时可能发生的超时和IO异常。

-- Set time out for your Httpclient -- and i think volley by default has a timeout.

- 为你的Httpclient设置超时 - 我认为凌空默认有超时。

#1


0  

In order to see if you have internet you have to do something more than check if you have a network connection. Because if your connected to a slow network, captive portal or a VPN you have a connection to the network but no actual internet or usable internet.

为了查看您是否有互联网,您必须做的不仅仅是检查您是否有网络连接。因为如果您连接到慢速网络,强制网络门户或VPN,您可以连接到网络,但没有实际的互联网或可用的互联网。

That's why you still need to check if you have internet/usable internet before you make a HTTP request by adding a simple ping to a server or Google (Because Google is up 99,99% of the time). You can also do it periodically or when you catch the first exception, that's up to you.

这就是为什么你仍然需要在发出HTTP请求之前检查你是否有互联网/可用的互联网,方法是向服务器或谷歌添加一个简单的ping(因为谷歌有99,99%的时间用户)。你也可以定期或当你发现第一个例外时,这取决于你。

public Boolean isInternet() {
    try {       
        Process process = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");      
        int returnVal = process.waitFor();      
        boolean reachable = (returnVal==0);
        return reachable
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return false; 
}

You can also use another method but the general idea is the same use something you know is almost always online and check if you can reach it.

您也可以使用其他方法,但一般的想法是相同的使用,你知道几乎总是在线,并检查你是否可以达到它。

However keep handling exceptions, because there is no way to always catch it and having a back up way of handling things can't hurt

但是要保持处理异常,因为没有办法总是抓住它并且有一个备份方式来处理事情不会受到伤害

#2


0  

How do I make sure the device is really connected to internet?

如何确保设备真正连接到互联网?

You have found out. That's what the errors are telling you.

你发现了。这就是错误告诉你的。

How do I make sure the device is really connected to internet? I actually perform these requests only if this function return true:

如何确保设备真正连接到互联网?我实际上只有在此函数返回true时才执行这些请求:

I'm not in favour of this sort of thing:

我并不赞成这种事:

  • if it tests exactly the same things as the actual request does, it is (i) duplicated work and (ii) not done at the same time
  • 如果它测试与实际请求完全相同的事情,则是(i)重复工作和(ii)不同时完成
  • if it doesn't test exactly the same things as the actual request, you are likely to get both false positives and false negatives
  • 如果它没有测试与实际请求完全相同的东西,那么你可能会得到误报和漏报
  • in all cases, it's an attempt to predict the future. It might fail now and the request succeed, or succeed now and the request fail.
  • 在所有情况下,它都是为了预测未来。它现在可能会失败并且请求成功,或者现在成功并且请求失败。
  • you have to write the error handling code for the request anyway.
  • 你必须为请求编写错误处理代码。

In general the best way to test whether any resource is available is just to try to use it in the normal way, and deal with any adverse consequences as and when they arise.

一般来说,测试任何资源是否可用的最佳方法是尝试以正常方式使用它,并在它们出现时处理任何不利后果。

Or should I just let it go and assume it is normal to get up to few hundreds of these warning per month?

或者我应该放手,并假设每月达到几百个这样的警告是正常的?

I wouldn't say ServerError is normal. It's possible that the server managed to send that to you over a fully functioning network, so it may be a server or client bug you need to investigate. Network outages on the other hand are 'normal' in any topology and technology.

我不会说ServerError是正常的。服务器可能设法通过功能完备的网络将其发送给您,因此可能是您需要调查的服务器或客户端错误。另一方面,网络中断在任何拓扑和技术中都是“正常的”。

#3


-1  

Yes you should check internet availability before making an HTTP request, it saves a lot for you.

是的,您应该在发出HTTP请求之前检查互联网可用性,这为您节省了很多。

The code you should is very good and far better than "pinging" any domain.

您应该使用的代码非常好,并且比“ping”任何域都要好得多。

But still in your case your condition isn't going to be sufficient, because the adapter is actually connected but you may not be able to connect to your server due to poor connection.

但仍然在你的情况下你的条件是不够的,因为适配器实际上是连接的,但由于连接不良,你可能无法连接到你的服务器。

So you should still handle time-out and IO exceptions that might happen while you're executing your requests.

因此,您仍应处理执行请求时可能发生的超时和IO异常。

-- Set time out for your Httpclient -- and i think volley by default has a timeout.

- 为你的Httpclient设置超时 - 我认为凌空默认有超时。