【问题标题】:App.OnResume error in Xamarin forms on Android and IOS devicesAndroid 和 IOS 设备上 Xamarin 表单中的 App.OnResume 错误
【发布时间】:2016-08-19 15:07:25
【问题描述】:

我们正在使用 xamarin 表单。在 Android 或 IOS 设备从后台恢复后,我们正在 .net 中进行由计时器触发的 REST 调用。 IOS 上的第一次尝试返回“描述符不是套接字”错误,Android 返回“连接被拒绝”错误。相同的代码在 Windows 中运行良好。所有 3 个平台的未来尝试(每隔几秒钟)都可以正常工作。有没有人看到这个并有解决办法?

代码

    //app on resume event
    protected async override void OnResume()
    {
        // Handle when your app resumes

        if (MainPage is RootPage)
        {
            RootPage mainPage = MainPage as RootPage;
            if (mainPage.Detail is NavigationPage)
            {
                NavigationPage nvPage = mainPage.Detail as NavigationPage;
                if(nvPage.CurrentPage is ThingsPage)
                {
                    ThingsPage thPage = nvPage.CurrentPage as ThingsPage;
                    thPage.TurnOnTimer();
                }
            }
        }
    }

    //code on the page
    public void TurnOnTimer()
    {
        if (viewModel != null)
        {
            viewModel.ContinueTimer = true;
            viewModel.StartAnotherTimer();
        }
    }

    //code in view model
    public async void StartAnotherTimer()
    {
        while (ContinueTimer)
        {
            try
            {
                DevicesUpdate devicesUpdate = await DataSource.GetDevices(LocationID, ControllerID, lastDevicesUpdateReceivedAt);

            }
            catch (Exception ex)
            {

            }

            // Update the UI (because of async/await magic, this is still in the UI thread!)
            if (ContinueTimer)
            {
                await Task.Delay(TimeSpan.FromSeconds(3));
            }
        }
    }

   public static async Task<DevicesUpdate> GetDevices(Guid locationID, Guid controllerID, DateTime lastUpdateReceivedAt)
    {

          DevicesUpdate devicesUpdate = await GetLastUpdatedDevices(controllerID, lastUpdateReceivedAt);
   }

    //code in view model
    public static async Task<DevicesUpdate> GetLastUpdatedDevices(Guid controllerID, 
                                                              DateTime lastUpdate)
{
    System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
    string url = string.Format("http://appname.azurewebsites.net/api/devices?controllerid={1}&lastUpdate={2}"
                                , Constants.WebServerURL, controllerID, lastUpdate);
    System.Net.Http.HttpResponseMessage response = await client.GetAsync(new Uri(url));
    string result = await response.Content.ReadAsStringAsync();
    if (response.IsSuccessStatusCode)
    {
        DevicesUpdate devices = JSONHelper.Deserialize<DevicesUpdate>(result);
        return devices;
    }
    else
    {
        if (response.ReasonPhrase == "UserException")
        {
            throw new UserException(result);
        }
        else
        {
            //throw error because the response from rest api is not a success
            throw new System.Net.Http.HttpRequestException(result);
        }
    }
}

【问题讨论】:

  • 您在 App.Resume 事件中执行此操作?你能添加一个小代码 sn-p 来解释你的问题吗?
  • 是的..它在 app.resume 事件中。我们正在使用 .net HttpClient 来调用 REST 服务。这是对 HTTP url 的标准 Client.GetAsync() 调用。代码在 PCL 中。
  • 您能否更新问题并发布您的App.OnResume 方法和底层服务调用的代码 sn-p(如果不是全部直接在该方法中)。
  • 该服务调用不在App.OnResume 中时是否有效?
  • 我已在问题中添加了代码 sn-p

标签: xamarin xamarin.ios xamarin.android xamarin.forms


【解决方案1】:

这里可能发生了一些导致问题的事情。

  • GetDevices 不返回任何内容。 (我希望你只是为了简洁而忽略了返回)
  • 您永远不会将 ContinueTimer 设置为 false。
  • 您使用的是哪个 iOS 版本?在以后的版本中,您必须使用 HTTPS 或明确允许非安全连接。这应该不是问题,因为 Azure 有 ssl。
  • 如果您打算在后台运行它,则需要将您的应用注册为后台进程。
  • 如果您不打算在后台运行它,您可能会遇到以前的尝试运行(或仍在尝试执行,或只是失败)然后调用更多的问题。

网络调用调用 3 秒定时器的原因是什么?如果调用时间超过 3 秒怎么办(那么即使第一次可能成功,您也会进行重复调用)。

如果您想让您的网络调用更加健壮,请查看Blog Post by Rob Gibbons,了解弹性网络调用。

我要做的第一件事是将它从计时器中删除,因为底层套接字似乎存在跨线程问题。

【讨论】:

  • 1. GetDevices 确实返回 devicesUpdate 对象,这里我没有包含它,因为 GetDevices 2 中有很多代码。 ContinueTimer 在两种情况下设置为 false,一种是页面的 OnDisappearing 事件,另一种是 App 的 OnSleep 事件。 3. iPad有9.3.4 iOS版本4。我希望页面数据在用户在屏幕上而不是在应用程序进入后台时刷新,并且计时器代码在Xamarin表单ViewModel中刷新数据。
  • 5.在计时器方法中,我有一个对 GetDevices 的等待调用,然后等待 Task.Delay 3 秒,所以首先代码将等待 GetDevices,何时等待 3 秒,3 秒后将调用 GetDevices,所以在这种情况下,我认为不会有重复的电话?在第一次调用未完成之前不会进行第二次调用,并且我正在获取基于日期和时间的数据以查看并返回基于日期和时间的更新数据
猜你喜欢
  • 2018-08-30
  • 2021-01-28
  • 2021-02-01
  • 1970-01-01
  • 2017-12-03
  • 2019-04-06
  • 2017-09-23
  • 2015-06-28
  • 1970-01-01
相关资源
最近更新 更多