Asynctask ArrayList对象没有从doInBackground传递给onPostExecute

时间:2014-04-30 20:43:37

标签: java android arraylist android-asynctask closures

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

经过多次搜索,我还没有找到如何在AsyncTask中返回对象的ArrayList的答案。

这是我在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;
    }

}

我正在AsyncTask中使用new LoadFriendCards(context).execute();执行onCreate

  • 预期输出: doInBackground应将ArrayList返回onPostExecute

  • 当前输出ArrayList<ServerTimeCard>onPostExecutedoInBackground的大小为AsyncTaskpublic 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. } } 中的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 的大小为零。

以下是{{1}}代码。

{{1}}

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

{{1}}

已解决:我原本以为我需要AsyncTask,但我最终删除了所有代码并将所有代码抛入我的Main类中的方法中。我在asynctask中同时运行了太多的东西,结构是在整个地方抛出数据。获得的经验:保持简单。

5 个答案:

答案 0 :(得分:1)

您正在修改匿名内部类中的result。你的代码没有看到你认为它看到的结果,而是一个闭包。这是问题的根源。

答案 1 :(得分:1)

您的问题是您使用findInBackground查询。该方法在后台线程中完成。所以你基本上是在异步任务中运行异步任务。

  1. doInBackground
  2. findInBackground - &gt;异步运行,因此代码执行继续
  3. 在您的查询完成之前调用
  4. onPostExecute
  5. 然后调用done回调让您的查询填满您的列表
  6. 因此,您需要做的是在findInBackground之外使用AsyncTask(该方法不打算在AsyncTask中使用)或使用find函数。 / p>

答案 2 :(得分:0)

您正在启动后台线程(您的异步任务),并在此处多次调用query.findInBackground(),这将启动更多后台线程。然而,这不是问题。

您遇到问题是因为AsyncTask在它启动的所有其他线程完成之前完成。您只知道在调用每个FindCallback的done()方法时其他线程都已完成。

如果您想知道正确的尺寸,则需要对其进行编码,以便检查上一个done()方法的尺寸。

答案 3 :(得分:0)

你不必让doInBackground返回一个可以在onPostExecute中使用的arraylist。回来&#34; ok&#34;或&#34;错误&#34;。声明并创建一个私人arraylist作为你的问题的成员。然后在doInBackground中填写它并在onPostexecute中使用它。

答案 4 :(得分:0)

另一种更简单的方法是将 doInBackground 声明为 List 类型。 这是我的例子

    @Override
    protected  ArrayList<ServerTimeCard > doInBackground(String... urls) {
        // Perform the HTTP request for earthquake data and process the response.
        ArrayList<ServerTimeCard > result = QueryUtils.fetchTheData(urls[0]);
        return result;
    }