我有一个片段,我想在其中解析一个JSON并创建一个具有其一些属性的ArrayList,然后将ArrayList的数据放入微调器。但是,我不知道我是否正在执行AsyncTask。每次我尝试一种新方法来解析片段活动中的 URL 中的 JSON 时,应用程序都会崩溃并显示"不幸的是,应用程序已停止"消息,或者微调器保持为空。我用日志验证了我从未到达AsyncTask上的onPostExecute()方法。问题:- 我做错了什么?- 我应该使用AsyncTask吗?
我的代码:
private class LoadResources extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.v(TAG, "pre-execute");
}
// Call after onPreExecute method
@Override
protected String doInBackground(String... urls) {
Log.v(TAG, "background");
Log.v(TAG, urls[0]);
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
try {
URL u = new URL(urls[0]);
BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream(), Charset.forName("UTF-8")));
StringBuilder sb = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
// the above parsing works, I've tested
JsonParser parser = new JsonParser();
JsonElement elem = parser.parse(sb.toString());
JsonArray array = elem.getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
JsonElement elem1 = array.get(i);
JsonArray tmpArr = elem1.getAsJsonArray();
for (JsonElement elem2 : tmpArr) {
elem2.getAsJsonObject().getAsJsonPrimitive().getAsString());
myArrayList.add(elem2.getAsJsonObject().getAsJsonPrimitive("name").toString());
return urls[0];
}
protected void onPostExecute(String params) {
Log.v(TAG, params);
}
}
在onCreateView上:
LoadResources loader = new LoadResources();
loader.execute("http://localhost:5000/avalidpath);
text = (AutoCompleteTextView) rootView.findViewById(R.id.nomeAluno);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_spinner_dropdown_item, myArrayList);
text.setAdapter(adapter);
text.setThreshold(3);
现在,当我滑动到此片段时,该应用程序停止工作。提前谢谢,伙计们。
您应该在doInBckground方法中完成繁重的工作。
onPostExecute(Result),在后台计算完成后在 UI 线程上调用。后台计算的结果作为参数传递给此步骤。文档在这里
编辑:
class LoadResources extends AsyncTask<String, Void, ArrayList<String>> {
Context context;
public LoadResources(Context context) {
this.context = context;
}
@Override
protected String doInBackground(String... urls) {
...
return myArrayList;
}
protected void onPostExecute(ArrayList<String> params) {
((YourActivity)context).setMyAdapter(params);
}
}
在您的活动(片段或其他内容)中:
public void setMyAdapter(ArrayList<String> params) {
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_spinner_dropdown_item, myArrayList);
text.setAdapter(adapter);
}
onPostExecute 是在 UI 线程上完成的。 你在这方面有太多的工作。 所有不直接影响UI元素的事情都应该在doInBackground中完成。 现在你的doInBackground什么都不做。
将整个代码从onPostExecute
移动到doInBackground
。您可以使用publishProgress(...);
和onProgressUpdate
将项目添加到列表中。或者在 AsyncTask 中创建本地列表,并在 onPostExecute
中将所有项目添加到全局列表中