2011-12-02 77 views
0

我得到的异常为 “* java.lang.IllegalStateException:适配器的内容已更改,但ListView没有收到通知。续 *适配器的耳鼻喉科是不是从后台线程修改,但只能从UI线程。Listview和适应抛出“java.lang.IllegalStateException:”

我的代码有两个线程一个是SAX解析,另一种是线程扩展的AsyncTask类

这每次ArrayList内容被改变时都检查内容。然后调用ada pter.notifyDatasetChange()方法在onProgressUpdate()..

但我希望输出作为解析器进行解析,尊重的元素应该是 添加到列表视图....请帮助我guyzzz .... 。 我有代码...

公共类SearchProperty扩展活动 {

boolean isDone; 
List<Property> properties = new ArrayList<Property>(); 
ListView list; 
ArrayAdapter<Property> adapter; 
InputStream in; 
ProgressDialog dialog; 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.newlay); 

    list = (ListView) findViewById(R.id.mylistview); 
    list.setPadding(0, 20, 0, 20); 
    dialog = new ProgressDialog(this); 
    dialog.setCancelable(true); 
    dialog.setMessage("Please Wait..."); 
    dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 

    adapter = new ArrayAdapter<Property>(this, 
      android.R.layout.simple_list_item_1, properties); 
    list.setAdapter(adapter); 

    list.setOnItemClickListener(new OnItemClickListener() 
    { 

     public void onItemClick(AdapterView<?> parent, View view, int pos, 
       long id) { 
      Toast.makeText(SearchProperty.this , "Please Wait... Application is under progress..." , Toast.LENGTH_SHORT).show(); 
     } 


    }); 

    FileParserTask task = new FileParserTask(); 

    Thread thread = new Thread(task); 
    thread.start(); 

    SetTimeoutTask task11 = new SetTimeoutTask(); 
    task11.execute(); 



    System.out.println("I m done!!"); 
} 

**// This thread is checking arraylist time to time after 50 ms and call on progressUpdate** 
private class SetTimeoutTask extends AsyncTask<String, Void, String> { 
    @Override 

    protected void onPreExecute() { 

     dialog.show(); 

    }; 
    protected String doInBackground(String... urls) 
    { 
    // Log.e("...","in do InBackground....."); 
     try { 
      for (;;) { 
       if (isDone) 
        break; 
       publishProgress(); 
       Thread.sleep(50); 

      } 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 
     dialog.dismiss(); 


    } 
    @Override 
    protected void onProgressUpdate(Void... values) 
    { 

     //Log.e("...","in onprogressupdate....."); 
     super.onProgressUpdate(values); 
     if(list.getAdapter()!=null) 
     adapter.notifyDataSetChanged(); 
    } 

} 


    **// this thread is doing parsing of xml file in background....** 

class FileParserTask implements Runnable { 

    @Override 
    public void run() { 


     try { 
      in = getAssets().open("property.xml"); 
      PropertyHandler myhandler = new PropertyHandler(properties); 
      XMLReader xmlReader = SAXParserFactory.newInstance() 
        .newSAXParser().getXMLReader(); 
      xmlReader.setContentHandler(myhandler); 
      xmlReader.parse(new InputSource(in)); 
      isDone = true; 
      System.out.println("Done!!!"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     // EstateParser.parse(in,properties,adapter); 
     catch (SAXException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ParserConfigurationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (FactoryConfigurationError e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

} 

}

回答

0

以代码的一些片断从上面:

List<Property> properties = new ArrayList<Property>(); 

然后,你必须

adapter = new ArrayAdapter<Property>(this, 
     android.R.layout.simple_list_item_1, properties); 
list.setAdapter(adapter); 

你描述你的代码的方式,看起来你是从FileParserTask添加到properties(甚至尽管我在上面的代码中看不到)。如果我是对的,并且您在FileParserTask中加入properties,那么很可能您会得到此错误。原因在于,您的下划线properties在非UI线程中进行了修改,这意味着您的ArrayAdapter也在非UI线程中进行了修改。

这会导致状态不一致,并且您会收到上述例外情况。尝试将解析器代码移至AsyncTask,稍作设计更改。

一个选项是将所有属性加载到单独的列表中,然后在onPostExecute中的ListView上创建并设置新的适配器。如果您不想在添加内容时看到更新的ListView,但您仍想查看进度状态,则此功能可用。

第二个选择是,创建一个临时列表来存储解析时的几个属性。当列表达到一定的限制(比如5),然后publishProgressonProgressUpdate,您可以将其添加到连接到适配器的其他List。注意:你可以试试这个来看它的行为。

+0

我不认为这将工作,因为doInBackgroundThread仍然在后台,所以解析那里仍然会修改另一个线程中的适配器。他只需要在OnProgressUpdate方法中触摸适配器。 – Kaediil

+0

右先生....但是,如果我将代码移动到AsyncTask,那么我得到的内容添加到ListView的结尾......我想要的内容应该添加到列表视图解析进步..但不是在结束。 – NullPointerException

+0

我同意@ Kaedil..you hv一些设计更改,因为我在我更新的答案中提到 – havexz

0

好吧,我猜你的处理程序SAX解析器直接更新支持ListView的数组?

那,我认为是问题所在。您需要为SAX解析器创建一个单独的列表,然后在onProgressUpdate调用期间将其转移到支持ListView的List,因为它位于UI线程中。

相关问题