我使用带有ListView
的{{1}}在CustomAdapter
中加载了很多项时出错了。
我在BaseAdapter
方法中使用CustomAdapter
。
onPostExecute
当启动另一个class setProjectsFilesNamesMap extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void...voids) {
//Fülle die Maps mit Daten
for (int position = 0; position < projectFileNamesMap.size(); position++) {
String filename = projectFileNamesMap.get(position);
setJobMap(filename);
setProjectMap(filename);
}
return null;
}
@Override
protected void onPostExecute(Void v){
CustomAdapterProjects adapter = new CustomAdapterProjects(ProjectsList.context, projectMap, jobMap);
setListAdapter(adapter);
}
}
并按下后退按钮时出现此错误并且应用程序崩溃:
Activity
修改 setMaps:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(16908298, class android.widget.ListView) with Adapter(class CustomAdapter.CustomAdapterProjects)]
getDOMElement:
public void setMaps(String filename) {
XMLParser parser = new XMLParser();
Document doc = parser.getDomElement(readProjectsFromFile(filename));
if (!(doc == null)) {
NodeList project = doc.getElementsByTagName(project);
for (int i = 0; i < project.getLength(); i++) {
HashMap<String, String> map = new HashMap<>();
Element e = (Element) project.item(i);
map.put(project_uuid, parser.getAttribute(e, project_uuid));
map.put(project_company, parser.getValue(e, project_company));
map.put(project_company_image, parser.getValue(e, project_company_image));
map.put(project_company_street, parser.getValue(e, project_company_street));
map.put(project_company_zip, parser.getValue(e, project_company_zip));
map.put(project_company_city, parser.getValue(e, project_company_city));
//map.put(project_company_country, parser.getValue(e, project_company_country));
projectMap.add(map);
}
NodeList job = doc.getElementsByTagName(job);
for (int i = 0; i < job.getLength(); i++) {
HashMap<String, String> map = new HashMap<>();
Element e = (Element) job.item(i);
map.put(job_uuid, parser.getAttribute(e, job_uuid));
map.put(job_subject, parser.getValue(e, job_subject));
map.put(job_description, parser.getValue(e, job_description));
//map.put(job_typ, parser.getValue(e, job_typ));
map.put(job_deadline, parser.getValue(e, job_deadline));
//map.put(job_task_count_all, parser.getValue(e, job_task_count_all));
//map.put(job_task_count_open, parser.getValue(e, job_task_count_open));
jobMap.add(map);
}
}
}
我必须在哪里使用 public Document getDomElement(String xml) {
Document doc;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(new ByteArrayInputStream(xml.getBytes()));
} catch (ParserConfigurationException e) {
Log.e("Error Parser: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error SAX: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error IO: ", e.getMessage());
return null;
}
return doc;
}
以及该方法是什么?
答案 0 :(得分:3)
doInBackground()
(顾名思义)在后台线程上运行。除非您使用数据发布转轮等,否则该线程中生成的数据(特别是添加到projectMap和jobMap的HashMaps)在另一个线程中不可用。幕后AsyncTask(以及其他内容)的作用是将数据从后台线程传递到UI线程。它从doInBackground()
到onPostExecute()
执行此操作。
您可以做的是修改AsyncTask,以便doInBackground()
返回您需要的数据(而不是返回null),然后将其用作onPostExecute()
中的参数。例如:
class setProjectsFilesNamesMap extends AsyncTask<Void,Void,HashMap<String, ArrayList<String> > >{
@Override
protected HashMap<String, ArrayList<String>> doInBackground(Void...voids) {
//Fülle die Maps mit Daten
HashMap<String, ArrayList<String>> data = new HashMap<String, ArrayList<String>>();
for (int position = 0; position < projectFileNamesMap.size(); position++) {
String filename = projectFileNamesMap.get(position);
ArrayList <String> jobMap = setJobMap(filename);
ArrayList <String> projectMap = setProjectMap(filename);
data.add("jobMap", jobMap);
data.add("projectMap", projectMap):
}
return data;
}
@Override
protected void onPostExecute(HashMap <String, ArrayList<String>> data){
CustomAdapterProjects adapter = new CustomAdapterProjects(ProjectsList.context, data.get("projectMap"), data.get("jobMap"));
setListAdapter(adapter);
}
}
当然这意味着你需要改变setJobMap和setProjectMap来返回地图,而不仅仅是设置它们。