2014-05-16 20 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); 
      } 
     } 
    } 
} 

发送广播的原因是它与活动无关。因此,如果当前显示的活动对同步过程的状态感兴趣,则只需注册两个广播的接收器即可。

否则将同步默默地在后台继续。

当然有很多变化的需要,以便它以符合你的情况,但我希望它显示的总体思路来进行。