简体   繁体   English

如何与多个AsyncTask同步应用

[英]How to sync app with multiple AsyncTask

I need To sync my app ( Sqlite to MySQL and Upload pics ) 我需要同步我的应用程序(将Sqlite同步到MySQL并上传图片)

Basically, I have one AsyncTask class per Table, and one class to upload. 基本上,每个表有一个AsyncTask类,还有一个要上载的类。 each line of 1 table may include several pics to upload. 1张桌子的每一行可能包含几张要上传的图片。

The thing is I can't find a way to control the state of the sync. 问题是我找不到控制同步状态的方法。 There is several ways to do it, as far I can see, but none of them is good for me: 据我所知,有几种方法可以做到这一点,但是没有一种对我有好处:

1.I could put all AsyncTask in one class, so each process go after the other, there is only one thread. 1.我可以将所有AsyncTask放在一个类中,因此每个进程都紧跟另一个进程,只有一个线程。

GOOD : It is easy to know when the process ends ( When entering in postExecute), so I can easily know if some process fails ( Checking in a global variable). 好的:很容易知道进程何时结束(在postExecute中输入),所以我可以很容易地知道某个进程是否失败(检入全局变量)。

BAD: This is slower, and putting all my code in one file is kind of bad, specially if there is a lot of table in my project ( and it will be) 不好:这比较慢,将我所有的代码放在一个文件中有点不好,特别是如果我的项目中有很多表的话(会这样)

2.Several AsyncTask GOOD: This approach is better, faster, and easy to maintain. 2,几个AsyncTask很好:这种方法更好,更快并且易于维护。 BAD: If I have 10 threads for instance, I can't know the moment when all the processes ends ( to check if there were errors in the processs. 不好:例如,如果我有10个线程,我不知道所有进程结束的那一刻(检查进程中是否有错误。

You can use the getStatus() method on all your tasks to see their status. 您可以在所有任务上使用getStatus()方法以查看其状态。

In your AsyncTask class: 在您的AsyncTask类中:

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

In your Activity class: 在您的Activity类中:

ArrayList<AsyncTask> tasks;

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

    return true;
}

Here is an outline of what I would do: 这是我要做什么的概述:

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);
            }
        }
    }
}

The reason for sending broadcasts is that it is Activity independent. 发送广播的原因是它与活动无关。 So, if the currently shown activity has interest in the status of the syncing process, it simply needs to register receivers for the two broadcasts. 因此,如果当前显示的活动对同步过程的状态感兴趣,则只需为两个广播注册接收者。

Otherwise the sync will continue silently in the background. 否则,同步将在后台静默继续。

There is of course a lot of changes that needs to be made in order for it to match your case but I hope it shows the general idea. 为了使它与您的情况相匹配,当然需要进行很多更改,但是我希望它能显示出总体思路。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM