异步任务 ArrayList 对象未从 doInBackground 传递到 onPostExecute

5 java android closures arraylist android-asynctask

我有一个AsyncTask接受上下文(使用onPostExecute)并运行doInBackground以从服务器返回对象的 ArrayList。当我执行它时,我可以看到它doInBackground运行良好,但是它没有将结果传递给onPostExecute.

经过大量搜索,我还没有找到如何在AsyncTask.

这是我正在创建doInBackground和使用的对象onPostExecute

public class ServerTimeCard {

    public String eventNameInput;
    Boolean isLocation, isImage, isVoice;

    public ServerTimeCard(String eventNameInput, boolean isLocation, boolean isImage, boolean isVoice) {
        this.eventNameInput = eventNameInput;
        this.isLocation = isLocation;
        this.isImage = isImage;
        this.isVoice = isVoice;
    }

}
Run Code Online (Sandbox Code Playgroud)

我正在执行AsyncTaskwith new LoadFriendCards(context).execute();in onCreate

  • 预期输出: doInBackground应该返回一个 ArrayList 到onPostExecute

  • 当前输出:当相同的数组列表 in具有更大的大小时,ArrayList<ServerTimeCard>inonPostExecute的大小为零doInBackground

以下是AsyncTask代码。

public class LoadFriendCards extends AsyncTask<Void, Void, ArrayList<ServerTimeCard>> {

            Context context;
            ArrayList<ServerTimeCard> result;

            public LoadFriendCards(Context context) {
                this.context = context;
            }

            @Override
            protected ArrayList<ServerTimeCard> doInBackground(Void... voids) {

                     result = new ArrayList<ServerTimeCard>();

                     // ...a bunch of data retrieval goes on here...    

                     // querying parse for object info
                     // adding a new object to the local ArrayList for all in db
                     for (String friend : friendsListNames) {
                          ParseQuery<ParseObject> query = ParseQuery.getQuery("TestObject");
                          query.whereEqualTo("accountName", friend+"@gmail.com");
                          query.findInBackground(new FindCallback<ParseObject>() {
                          public void done(List<ParseObject> objects, ParseException e) {
                          if (e == null) {

                               for (ParseObject cardInfo : objects) {

                                   ServerTimeCard item = new ServerTimeCard(
                                      cardInfo.getString("eventName"),
                                      cardInfo.getBoolean("isImage"),
                                      cardInfo.getBoolean("isImage"),
                                      cardInfo.getBoolean("isVoice"));

                                   result.add(item);


                        Log.e("New item called: ", String.valueOf(item.eventNameInput));
                        Log.e("New size of array...", String.valueOf(result.size()));

                    }

                } else {
                    Log.d("info", "Error: " + e.getMessage());
                }
            }
        });
    }

                // returning the new ArrayList<ServerTimeCard> to onPostExecute

                // PROBLEM: THE SIZE OF THE RESULT IS 0
                Log.e("Size of passing array", String.valueOf(result.size()));

                return result;
            }

            @Override
            protected void onPostExecute(ArrayList<ServerTimeCard> result) {

                // PROBLEM: This returns 0
                Log.e("Data list size: ", String.valueOf(result.size())); 

                // trying to use all objects in the arraylist here but it doesn't work
                // due to the size. Something isn't passing correctly.

            }
        }
Run Code Online (Sandbox Code Playgroud)

Log.e 的 Logcat 输出:(看起来它调用 doInBackground,然后是 onPostExecute,然后又是 doInBackground)

E/Size of passing array? 0
E/Data list size:? 0
E/New item called:? yah
E/New size of array...? 1
E/New item called:? lplokolol
E/New size of array...? 2
E/New item called:? It works
E/New size of array...? 3
Run Code Online (Sandbox Code Playgroud)

已解决:我最初认为我需要 AsyncTask 但我最终将其全部删除并将所有代码扔到我的 Main 类中的一个方法中。我在 asynctask 中同时运行了太多东西,并且该结构将数据扔到了所有地方。经验教训:保持简单。

sin*_*hum 2

您的问题是您正在使用findInBackground进行查询。该方法是在后台线程中完成的。因此,您基本上是在异步任务中运行异步任务。

  1. doInBackground
  2. findInBackground-> 异步运行,以便代码继续执行
  3. onPostExecute在查询完成之前调用。
  4. 然后会回调done您的查询来填充您的列表

因此,您需要做的是要么在findInBackgroundan 外部使用AsyncTask(该方法不应在 AsyncTask 中使用),要么使用find函数。