NameResolutionFailure梦魇:即使ModernHttpClient也失败了

时间:2015-10-01 04:54:51

标签: c# xamarin mvvmcross

当我在MVVM Cross Android应用程序中发出Web请求(GET)时,我经常遇到ModernHttpClient错误。

我已经尝试了论坛中提供的大部分建议,因为它是一个常见的,但我无法解决这个问题。

我当前的尝试使用NuGet包HttpWebRequest来执行Web请求。发生同样的错误 - 无法将域解析为IP - 但是错误消息与我使用ModernHttpClient时发生的情况略有不同所以我猜这有点小改进?

  

java.net.UnknownHostException:无法解析主机" jsonplaceholder.typicode.com":没有与主机名关联的地址

您能否提供有关为何总是失败的建议?也许它的方法不能真正地利用IRestService

以下代码是位于Core PCL中而不是Android项目中的public async Task MakeRequest(WebHeaderCollection headers = null) { var handler = new NativeMessageHandler(); string requestUrl = "http://jsonplaceholder.typicode.com/posts/1"; try { using (var client = new HttpClient(handler)) { //client.BaseAddress = new Uri(baseAddress); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await client.GetAsync(requestUrl); if (response.IsSuccessStatusCode) { var stream = await response.Content.ReadAsStreamAsync(); var reader = new StreamReader(stream); Mvx.Trace("Stream: {0}", reader.ReadToEnd()); } } } catch (WebException ex) { Mvx.Trace("MakeRequest Error: '{0}'", ex.Message); } return; } 类的一部分。

> Caused by: java.lang.UnsatisfiedLinkError: Couldn't load pjsua2 from
> loader
> dalvik.system.PathClassLoader[dexPath=/data/app/org.pjsip.pjsua2.app-2.apk,libraryPath=/data/app-lib/org.pjsip.pjsua2.app-2]:
> findLibrary returned null.

dlopen("/data/app-lib/org.pjsip.pjsua2.app-2/libpjsua2.so") failed: Cannot load library: load_library(linker.cpp:766): not a valid ELF executable: /data/app-lib/org.pjsip.pjsua2.app-2/libpjsua2.so

PS:我还试图使用Cheesebarons ModernHttpClient MVVM Cross插件,但是这会在发布模式下导致编译错误,并且没有关于它有哪些方法和类的文档 - 可能它不再受支持?

PPS:是的,我的清单有互联网权限(我检查选项和实际的清单文件以确认)

1 个答案:

答案 0 :(得分:3)

不再需要MvvmCross的ModernHttpClient插件,所以不要使用它。

因此,由于您在AndroidManifest中设置了Internet权限,因此问题就是其他问题。我在一些Android设备上经历过,第一次调用某些Internet资源失败并出现同样的错误。我通常使用的方法是重试呼叫。

有多种方法可以做到这一点。

  1. 您可以创建自己的HttpClientHandler,它包装来自ModernHttpClient的HttpClientHandler,并在那里创建自己的重试处理。
  2. 您可以使用像Polly这样的库重试
  3. 我倾向于做后者。因此,如果您添加Polly NuGet,您可以很快地测试这是否能为您解决问题:

    var policy = Policy.WaitAndRetryAsync(
        5, 
        retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
        (ex, span) => {
            Mvx.Trace("Retried because of {0}", ex);
        }
    );
    

    然后重试您的任务,如:

    await policy.ExecuteAsync(() => MakeRequest(someHeaders)).ConfigureAwait(false);
    

    通常在第二次尝试时,异常就会消失。

    我在Nexus 5,Nexus 7和三星Galaxy SII上看到过这个问题,但在其他设备上却没有。如果您在调试之前切换设备上的WiFi,也可能会有所帮助。

    在任何情况下,你的应用都应该有某种重试逻辑,因为有时互联网连接可能会不稳定。