【发布时间】:2015-04-26 05:09:32
【问题描述】:
这就是我想要做的事情:当从弹出窗口中的项目列表中选择项目时,从远程服务器获取 JSON 数组并在列表视图(在新活动中)呈现它。当单击/点击活动中的元素时会创建弹出窗口。更具体地说:活动在网格视图中显示类别列表。每个类别都有一堆子类别,当用户单击类别时,这些子类别在弹出窗口中显示为项目列表。当用户在弹出窗口中选择一个项目时,会创建一个新活动,显示该子类别中的项目列表。项目详细信息作为 JSON 数组从远程服务器获取。 当从弹出窗口中选择子类别时,我创建了一个 AsyncTask 从服务器获取项目详细信息。以下是用于此的代码 sn-p。
public class Section extends Fragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
mGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView <? > parent, final View v, nt position, long id) {
...
PopupMenu popup = new PopupMenu(getActivity(), v);
...
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
new GetProductDataFromServer_Task().execute(productURL);
Intent intent = new Intent(getActivity(), ProductListScreen.class);
startActivity(intent);
return true;
}
});
});
}
return rootView;
}
}
片段是用于在网格布局中显示类别列表的活动的一部分。
而且,这里是从服务器获取 JSONArray 的 AsyncTask。
private class GetProductDataFromServer_Task extends AsyncTask < String, Long, JSONObject > {
@Override
protected JSONObject doInBackground(String...params) {
HttpEntity httpEntity = null;
HttpGet httpGet = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
httpGet = new HttpGet(params[0]);
HttpResponse httpResponse = httpClient.execute(httpGet);
httpEntity = httpResponse.getEntity();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Convert HttpEntity into JSON Array
JSONObject jsonObject = null;
if (httpEntity != null) {
try {
String entityResponse = EntityUtils.toString(httpEntity);
jsonObject = new JSONObject(entityResponse);
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
return jsonObject;
}
@Override
protected void onPostExecute(JSONObject jsonObject) {
try {
JSONArray products = jsonObject.getJSONArray("products");
int numProducts = products.length();
mProductList = new ProductInfoForGridView[numProducts];
for (int prodIdx = 0; prodIdx < numProducts; prodIdx++) {
mProductList[prodIdx] = GetProductObjFromJSONObj(products.getJSONObject(prodIdx));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
我面临的问题是 onPostExecute() 由于某种原因没有被调用。 JSONArray 已成功从服务器获取,并且 doInBackground() 函数完成了它的执行,没有任何异常。我怀疑这与嵌套事件侦听器有关,因为如果我从类别侦听器启动异步任务(即在 onItemClick() 中 - 调用嵌套子类别侦听器 setOnMenuItemClickListener() 的函数),它就可以正常工作。
提前感谢您的回答。我试图在我的问题中进行描述。如果需要,我很乐意提供更多详细信息。
【问题讨论】:
-
您是从主 (UI) 线程执行异步任务吗?否则 onPostExecute 不会被调用。
-
这里是导航流程:启动屏幕 -> 类别屏幕(实现水平分页 - 每个选项卡创建并分配一个片段)-> Fragment:onCreateView -> mGrid.setOnItemClickListener:onItemClick() -> 弹出.setOnMenuItemClickListener:onMenuItemClick() -> (new GetProductDataFromServer_Task().execute(productURL);) 。我的理解是导致创建 AsyncTask 的所有活动都发生在 UI 线程上。如果我错了,请纠正我。
-
更新...当我在 AsynTask 开始和使用由来自远程服务器的 AsyncTask。我从这种行为中推断出,网络延迟在阻止 Android 框架调用 onPostExecute() 方面起到了一定的作用。我计划处理此问题的方式是显示“正在加载...”消息,直到我收到所有数据然后开始新活动。如果有人可以提出更好的解决方案,我将不胜感激。谢谢