2017-08-13 40 views
1

我們有一個Xamarin表單應用程序在後臺API調用期間關閉。我沒有在這個項目上編寫很多同步代碼,但我仍然排除故障。這是一個什麼樣的代碼是做一個總結:Xamarin格式AbstractThreadedSyncAdapter關閉時沒有錯誤或異常

  1. API調用出去併成功
  2. 返回的JSON字符串被正確序列化到C#對象的列表。
  3. 對象被傳遞給一個方法,該方法將它們映射到只包含我們關心應用程序的屬性的本地類。
  4. 在映射之後,我們將這些對象插入到sql lite數據庫中。

在循環瀏覽該對象列表並映射它們的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. 看起來他在另一個線程上關閉了它,如果是這樣的話,爲什麼整個應用程序關閉,而不僅僅是同步過程?

這裏是正在發生的事情在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   
    } 
} 

--update 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

有你檢查應用程序輸出/設備日誌是否有任何崩潰信息?你確定它不是由未處理的異常造成的嗎? – Jason

+0

我會開始註釋代碼並查看是什麼原因導致的,並從插入數據庫開始。 –

回答

0

我的理論是,SyncAdapter結束後的API調用它做作出任何網絡流量,但仍留下了一堆的處理和db寫道。 Xamarin沒有看到網絡流量,並說「嗨,你已經完成了同步」,然後在它仍在運行的過程中殺死這個進程,這與整個應用程序運行的進程是一樣的。發生這種情況時沒有任何明確的警告,只是發生。

因此,我所做的只是爲每個帶有id和更新時間的記錄拉回一個小對象,然後逐個循環(不能並行執行,因爲您運行回到同樣的問題) - 似乎解決方案是保持一些網絡活動在整個過程中嗡嗡作響。

它可能會更好,以便能夠拉回來的數據,並且將其傳遞給別的東西,但我不得不研究的做事方式xamarin多一點去弄清楚