如何使用多个AsyncTask同步应用程序

时间:2014-05-16 14:43:16

标签: android mysql multithreading sqlite android-asynctask

我需要同步我的应用程序(Sqlite到MySQL和上传图片)

基本上,我每个表都有一个AsyncTask类,还有一个要上传的类。 1个表的每一行可能包含几个要上传的图片。

问题是我无法找到控制同步状态的方法。 我可以看到,有几种方法可以做到这一点,但它们都不适合我:

1.我可以把所有的AsyncTask放在一个类中,所以每个进程都在另一个进程之后,只有一个线程。

GOOD:很容易知道进程何时结束(当进入postExecute时),因此我可以很容易地知道某个进程是否失败(检入全局变量)。

坏:这个比较慢,将我的所有代码放在一个文件中都很糟糕,特别是如果我的项目中有很多表(并且它会是)

2.几个AsyncTask  好的:这种方法更好,更快,更易于维护。  坏:如果我有10个线程,我不知道所有进程结束的时刻(检查进程中是否有错误。

2 个答案:

答案 0 :(得分: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 :(得分: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);
            }
        }
    }
}

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

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

当然,为了使其与您的案例相匹配,需要做出很多改变,但我希望它能显示出一般的想法。