我有一个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>
中onPostExecute
中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.
}
}
中的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中同时运行了太多的东西,结构是在整个地方抛出数据。获得的经验:保持简单。
答案 0 :(得分:1)
您正在修改匿名内部类中的result
。你的代码没有看到你认为它看到的结果,而是一个闭包。这是问题的根源。
答案 1 :(得分:1)
您的问题是您使用findInBackground查询。该方法在后台线程中完成。所以你基本上是在异步任务中运行异步任务。
doInBackground
findInBackground
- &gt;异步运行,因此代码执行继续onPostExecute
。done
回调让您的查询填满您的列表因此,您需要做的是在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;
}