2011-12-02 62 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線程中。

相關問題