我们有一个Xamarin表单应用程序在后台API调用期间关闭。我没有在这个项目上写下大部分同步代码,但我还是对它进行了故障排除。以下是代码正在执行的操作的摘要:
在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
我的怀疑是,在应用程序关闭时,同步已经完成了任何网络调用,但仍然处理所有映射和数据库插入结果数据。所以:
以下是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;
}
}
答案 0 :(得分:0)
我的理论是,在SyncAdapter完成API调用后,它完成了任何网络流量,但仍然留下了大量处理和数据库写入。 Xamarin没有看到任何网络流量并说'嘿,你已经完成了同步&#34;然后在它仍在运行时终止该进程,这与整个应用程序运行的过程相同。当这种情况发生时,没有任何明确警告你,它只会发生。
所以我所做的只是为每个记录的一个小对象拉回id和更新的时间,然后逐个循环它们(你不能并行执行它因为你运行回到同样的问题) - 似乎解决方案是在你仍然需要工作的整个过程中保持一些网络活动。
能够撤回数据并将其传递给其他东西可能会更好,但是我必须研究xamarin做事情的方式来解决这个问题