Xamarin表单AbstractThreadedSyncAdapter关闭时没有错误或异常

时间:2017-08-13 16:15:19

标签: xamarin.forms

我们有一个Xamarin表单应用程序在后台API调用期间关闭。我没有在这个项目上写下大部分同步代码,但我还是对它进行了故障排除。以下是代码正在执行的操作的摘要:

  1. api呼叫熄灭并成功返回
  2. json字符串被正确序列化为C#对象列表。
  3. 将对象传递给一个方法,该方法将它们映射到一个本地类,该类只包含我们在应用程序上关注的属性。
  4. 在此映射之后,我们将这些对象插入到sql lite数据库中。
  5. 在3期间的某个时刻循环浏览对象列表并映射它们,应用程序只是关闭而不会抛出任何异常。我已经尝试命令对象查看是否有与导致崩溃的数据相关的内容,我无法检测到那里的任何模式。有时它会在15,20,27个对象之后崩溃,所以我不认为它与数据问题有关。这里的代码非常基本:foreach循环和一个将属性从一个类分配给另一个类的基本方法,如果它是代码的问题,我希望看到抛出异常。

    我确定我的第一步是找到一些Xamarin技巧来实际报告导致崩溃的原因。对于它的价值,我们在Android和iOS上都观察到了这种行为。

    - 更新 -

    我希望能够缩小问题的范围。我从Xamarin文档中找到了一些信息:

    the framework will attempt to determine whether or not an adapter is making 
    progress by monitoring its network activity over the course of a minute. If 
    the network traffic over this window is close enough to zero the sync will 
    be cancelled.
    

    Android.Content.AbstractThreadedSyncAdapter Class

    我的怀疑是,在应用程序关闭时,同步已经完成了任何网络调用,但仍然处理所有映射和数据库插入结果数据。所以:

    1. 我怎么知道是否是这种情况?我尝试添加OnSyncCanceled()方法,该方法在应用程序关闭的情况下从未在调试器中点击。
    2. 看起来他在另一个帖子上关闭它,如果是这样的话,为什么整个应用程序关闭,而不仅仅是同步过程?
    3. 以下是SyncAdapter中发生的事情

      public class SyncAdapterImpl : AbstractThreadedSyncAdapter
      {
          public SyncAdapterImpl(Context context, bool autoInitialize)
              : base(context, autoInitialize)
          {
          }
      
          public override void OnSyncCanceled()
          {
              base.OnSyncCanceled();
              Console.WriteLine("Canceled");
          }
      
          public override void OnPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
          {
              IKernel kernel = new StandardKernel(new PlatformModule(), new CoreModule());
              var syncService = kernel.Get<SyncService>();
              SyncResultSummary syncResultSummary = new SyncResultSummary();
              if (!extras.GetBoolean(ContentResolver.SyncExtrasUpload))
              {
                  syncService.UpdateProfile().Wait();
                  var task = syncService.DownloadJobs();
                  task.Wait();
                  syncResultSummary = task.Result;
              }
      
              // send notifications with results          
          }
      }
      

      - 更新2 -

      我注意到将Process = ":sync"添加到SyncAdapterService类会阻止整个应用被杀死,但是,同步本身现在也会失败。

      [Service(Label = "SyncAdapterService", Exported = true, Process = ":sync")]
      [IntentFilter(new String[] { "android.content.SyncAdapter" })]
      [MetaData("android.content.SyncAdapter", Resource = "@xml/syncadapter")]
      public class SyncAdapterService : Service
      {
          private SyncAdapterImpl _syncAdapter;
          private object _syncAdapterMutex = new object();
      
          public override void OnCreate()
          {
              base.OnCreate();
              lock(_syncAdapterMutex)
              {
                  if (_syncAdapter == null)
                      _syncAdapter = new SyncAdapterImpl(this.ApplicationContext, true);
              }
          }
      
          public override IBinder OnBind(Intent intent)
          {
              return _syncAdapter.SyncAdapterBinder;
          }
      }
      

1 个答案:

答案 0 :(得分:0)

我的理论是,在SyncAdapter完成API调用后,它完成了任何网络流量,但仍然留下了大量处理和数据库写入。 Xamarin没有看到任何网络流量并说'嘿,你已经完成了同步&#34;然后在它仍在运行时终止该进程,这与整个应用程序运行的过程相同。当这种情况发生时,没有任何明确警告你,它只会发生。

所以我所做的只是为每个记录的一个小对象拉回id和更新的时间,然后逐个循环它们(你不能并行执行它因为你运行回到同样的问题) - 似乎解决方案是在你仍然需要工作的整个过程中保持一些网络活动。

能够撤回数据并将其传递给其他东西可能会更好,但是我必须研究xamarin做事情的方式来解决这个问题