Sequential AsyncTasks,以下使用来自先前的结果

问题描述 投票:0回答:1

我对此有所考虑,我想知道哪种方法可能是完成我的请求的最佳方式。

实际情况:

我有许多Web调用,这些调用必须是连续的,并且每个调用都必须使用前一个的结果。这就是我的意思的概念:

假设具有此数据库结构:

  • 用户[id,服务器端创建的信息,信息]
  • 房屋[id,服务器端创建的信息,用户参考,信息]
  • 房间[id,服务器端创建的信息,房屋参考,信息]

假设用户通过我的应用程序(离线)可以创建他的用户实体,每个房屋N个房屋实体和N个房间实体。

然后,完成后,用户正在与服务器同步数据。

这是应该做的:

  1. 对于每个用户,将用户发送到webapi并阅读服务器端信息。
  2. 对于已发送用户的每个房屋,请读取服务器端信息,将房屋发送到webapi并读取服务器端信息。
  3. 对于已发送房屋的每个房间,请阅读服务器端信息,将该房间发送到webapi并阅读服务器端信息。

这可以通过这种方式完成:

  • 创建一个AtomicInteger,它是要完成的所有同步的计数。

使用用户,房屋,房间的总和来初始化此值。

void syncDone() {
  if(totalSyncCounter.decrementAndGet() == 0){
    //sync finished, prompt user
  }
}

创建AsyncTasks

class SendUserToDbAsyncTask extends AsyncTask<User, Void, Integer> {

    UserSavedCallback _callback;

    public SendUserToDbAsyncTask(UserSavedCallback _callback) {
        this._callback = _callback;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Integer doInBackground(User... users) {
        //save user and return the server-side value
        return serverSideInfo;
    }

    @Override
    protected void onPostExecute(Integer res) {
        super.onPostExecute(res);
        _callback.onResult(res);
    }
}

class SendHouseToDbAsyncTask extends AsyncTask<House, Void, Integer> {

    HouseSavedCallback _callback;

    public SendHouseToDbAsyncTask(HouseSavedCallback _callback) {
        this._callback = _callback;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Integer doInBackground(House... houses) {
        //save user and return the server-side value
        return serverSideInfo;
    }

    @Override
    protected void onPostExecute(Integer res) {
        super.onPostExecute(res);
        _callback.onResult(res);
    }
}

class SendRoomToDbAsyncTask extends AsyncTask<User, Void, Integer> {

    RoomSavedCallback _callback;

    public SendRoomToDbAsyncTask(RoomSavedCallback _callback) {
        this._callback = _callback;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Integer doInBackground(Room... rooms) {
        //save user and return the server-side value
        return serverSideInfo;
    }

    @Override
    protected void onPostExecute(Integer res) {
        super.onPostExecute(res);
        _callback.onResult(res);
    }
}

逻辑:

void DoStuffs() {

  mySyncCounter = [users + houses + rooms];
  for (User user : users) {
    new SendUserToDbAsyncTask(new UserSavedCallback() {
      void onResult(){
        syncDone();
        for (House house : user.houses) {
          new SendHouseToDbAsyncTask(new HouseSavedCallback() {
            void onResult(){
              syncDone();
              for (Room room : house.rooms) {
                new SendRoomToDbAsyncTask(new RoomSavedCallback() {
                  void onResult(){
                    syncDone();
                }).execute(room);
              }
          }).execute(house);
        }
    }).execute(user);
  }
}

当然,这只是SO上手工编写的示例。我只是想让你明白这一点。我知道我可以对所有人进行单个回调,可以在方法之外初始化它,只需为所有内容创建单个asynctask,等等...但是我没有寻找有关优化此特定代码的任何建议,我只是想知道如何执行多个顺序异步操作,其中每个后续操作都使用上一个操作的返回。

执行这种操作的最佳方法是什么?

是否有一种“清洁”的方式?

谢谢

java android optimization android-asynctask
1个回答
0
投票

如果我理解正确,您可以使用ExecutorService调用同步服务器,并使用Semaphore根据需要停止线程

© www.soinside.com 2019 - 2024. All rights reserved.