2014-05-16 24 views
1

我需要同步我的應用程序(的SQLite到MySQL和上傳圖片)如何同步多的AsyncTask

基本上,我有每一個表類的AsyncTask,而一個類上傳。 1表中的每行可能包含幾張要上傳的圖片。

的事情是我無法找到一個方法來控制同步的狀態。 有幾種方法可以做到這一點,儘管我可以看到,但它們都不適合我:

1.我可以將所有AsyncTask放在同一個類中,因此每個進程都在另一個類之後,一個線程。

GOOD:這是很容易知道該過程結束(當postExecute進入)時,如果某個進程失敗(在一個全局變量檢查),我可以很容易地知道。

BAD:這會慢一些,並把我所有的代碼在一個文件中是有種不好的,特別是如果在我的項目有很多表(這將是)

2.Several的AsyncTask GOOD :這種方法更好,更快,並且易於維護。 不好意思:如果我有10個線程,例如我不知道所有進程結束的時刻(檢查進程中是否有錯誤)

+0

關於若干的AsyncTask,你總是可以簡單地運往一個回調接口與每個任務,發送狀態返回到主線程,成功,進步,失敗。那或者發送廣播,可能是一個相對容易的解決方案。 – cYrixmorten

回答

1

您可以在所有任務上使用getStatus()方法他們的狀態

在你的AsyncTask類:

@Override 
public void onPostExecute(Object result) { 
    if (isSyncFinished()) { 
     //Do whatever 
    } 
}  

在你的Activity類:

ArrayList<AsyncTask> tasks; 

private Boolean isSyncFinished() { 
    for (AsyncTask task : tasks) { 
     if (task.getStatus() == AsyncTask.Status.RUNNING) 
      return false; 
    } 

    return true; 
} 
1

這裏的輪廓我會做什麼:

public class SyncDatabase { 

    public static final int RESULTCODE_SUCCESS = 1; 
    public static final int RESULTCODE_FAIL_IO_FAILURE = 2; 
    public static final int RESULTCODE_FAIL_NO_CONNECTION = 3; 

    private interface SyncStatusCallback { 
     public void success(String table); 
     public void failed(String table, int resultCode); 
    } 

    private Context context; 

    public SyncDatabase(Context context) { 
     // application context to not rely on a single activity 
     context = context.getApplicationContext(); 
    } 

    public void sync() { 
     StandardSyncStatusCallback syncCallback = new StandardSyncStatusCallback(); 
     new SyncTable1(syncCallback).execute(); 
     new SyncTable2(syncCallback).execute(); 
     new SyncTable3(syncCallback).execute(); 
     ... 
    } 

    private class StandardSyncStatusCallback implements SyncStatusCallback { 

     @Override 
     public void success(String table) { 
      Intent intent = new Intent("DATABASE_SYNC_SUCCESS"); 
      intent.putExtra("table", table); 
      context.sendBroadcast(intent); 
     } 

     @Override 
     public void failed(String table, int resultCode) { 
      Intent intent = new Intent("DATABASE_SYNC_FAILED"); 
      intent.putExtra("table", table); 
      intent.putExtra("resultCode", resultCode); 
      context.sendBroadcast(intent); 
     } 

    } 


    private class SyncTable1 extends AsyncTask<Void, Void, Integer> { 

     private final String tableName = "table1"; 

     private final SyncStatusCallback syncStatusCallback; 

     public SyncTable1(SyncStatusCallback syncStatusCallback) { 
      this.syncStatusCallback = syncStatusCallback; 
     } 

     @Override 
     protected void onPreExecute() { 

     } 

     // The code to be executed in a background thread. 
     @Override 
     protected Integer doInBackground(Void... p) { 
      // perform sync and return resultCode 
      return 1; 
     } 

     // after executing the code in the thread 
     @Override 
     protected void onPostExecute(Integer resultCode) { 
      if (resultCode == 1) { 
       syncStatusCallback.success(tableName); 
      } else { 
       syncStatusCallback.failed(tableName, resultCode); 
      } 
     } 
    } 
} 

發送廣播的原因是它與活動無關。因此,如果當前顯示的活動對同步過程的狀態感興趣,則只需註冊兩個廣播的接收器即可。

否則將同步默默地在後臺繼續。

當然有很多變化的需要,以便它以符合你的情況,但我希望它顯示的總體思路來進行。