2013-04-25 189 views
0

我在我的代碼中有一個奇怪的行爲:與asyncTask在模擬器上解析本地xml文件比在主線程上解析它需要更長的時間。Xml與AsyncTask解析比在主線程解析慢慢線程

這裏是我的代碼的AsyncTask:

public class MostraTutti extends SherlockActivity { 
ListView lv; 
final List<ListViewItem> items = new ArrayList<MostraTutti.ListViewItem>(); 
final ArrayList<String> nome = new ArrayList<String>(); 
final ArrayList<String> immagine = new ArrayList<String>(); 
... 

final int array_image2[] ={R.drawable.iodocloroidrossichinolina,R.drawable.acidoacetilsalicilico, 
     ...}; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.mostra_tutti); 
    lv = (ListView) findViewById(R.id.listView); 
    getSupportActionBar().setDisplayShowHomeEnabled(false); 

    RssFeedTask rssTask = new RssFeedTask(); 
     rssTask.execute(); 

} 

private class RssFeedTask extends AsyncTask<String, Void, String> { 
    private ProgressDialog Dialog; 
    String response = ""; 

    @Override 
    protected void onPreExecute() { 
     Dialog = new ProgressDialog(MostraTutti.this); 
     Dialog.setMessage("Leggo le sostanze..."); 
     Dialog.show(); 
    } 

     @Override 
     protected String doInBackground(String... urls) { 
      InputStream xmlFile = getResources().openRawResource(R.raw.sostanze); 
      try { 

      DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 
      final Document document = documentBuilder.parse(xmlFile); 
      document.getDocumentElement().normalize(); 
      NodeList nodeList = document.getElementsByTagName("sostanza"); 

      for (int i = 0; i < nodeList.getLength(); i++) { 
      final int indice = i; 

      nome.add(document.getElementsByTagName("nome").item(indice).getTextContent()); 
      iupac.add(document.getElementsByTagName("iupac").item(indice).getTextContent()); 
      aspetto.add(document.getElementsByTagName("aspetto").item(indice).getTextContent()); 
      formula.add(document.getElementsByTagName("formula").item(indice).getTextContent()); 
      immagine.add(document.getElementsByTagName("immagine").item(indice).getTextContent()); 
      appartenenza.add(document.getElementsByTagName("appartenenza").item(indice).getTextContent()); 
      spiegazione.add(document.getElementsByTagName("spiegazione").item(indice).getTextContent()); 
      tempFus.add(document.getElementsByTagName("temperaturaFusione").item(indice).getTextContent()); 
      tempEboll.add(document.getElementsByTagName("temperaturaEbollizione").item(indice).getTextContent()); 
      solubilita.add(document.getElementsByTagName("solubilita").item(indice).getTextContent()); 
      note.add(document.getElementsByTagName("eccezioni").item(indice).getTextContent()); 

      String str = document.getElementsByTagName("formula").item(indice).getTextContent(); 

      str = str.replaceAll("0", "\u2080"); 
      str = str.replaceAll("1", "\u2081"); 
      str = str.replaceAll("2", "\u2082"); 
      str = str.replaceAll("3", "\u2083"); 
      str = str.replaceAll("4", "\u2084"); 
      str = str.replaceAll("5", "\u2085"); 
      str = str.replaceAll("6", "\u2086"); 
      str = str.replaceAll("7", "\u2087"); 
      str = str.replaceAll("8", "\u2088"); 
      str = str.replaceAll("9", "\u2089"); 

      final String stringa = str; 
      formulaConvertita.add(stringa); 

        //CustomListViewAdapter adapter = new CustomListViewAdapter(MostraTutti.this,items); 
        //lv.setAdapter(adapter); 
        items.add(new ListViewItem() 
        {{ 
         ThumbnailResource = array_image2[indice]; 
         Title = document.getElementsByTagName("nome").item(indice).getTextContent(); 
         SubTitle = stringa; 
        }}); 
      }; 

     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } catch (ParserConfigurationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (SAXException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return response; 
} 
     @Override 
     protected void onPostExecute(String result) { 
      Dialog.dismiss(); 
      CustomListViewAdapter adapter = new CustomListViewAdapter(MostraTutti.this,items); 
      lv.setAdapter(adapter); 

      lv.setOnItemClickListener(
        new OnItemClickListener() 
        { 
         public void onItemClick(AdapterView<?> arg0, View v, int position, long id) 
         {       
          Context context = getBaseContext(); 
          Intent myIntent = new Intent(context, Dettagli.class); 

          myIntent.putExtra("nome_sostanza",nome.get(position)); 
         // myIntent.putExtra("formula",formula.get(position)); 
          myIntent.putExtra("iupac",iupac.get(position));     
          myIntent.putExtra("aspetto",aspetto.get(position));     
          myIntent.putExtra("appartenenza",appartenenza.get(position)); 
          myIntent.putExtra("solubilita",solubilita.get(position)); 
          myIntent.putExtra("tempFus",tempFus.get(position)); 
          myIntent.putExtra("tempEboll",tempEboll.get(position)); 
          myIntent.putExtra("spiegazione",spiegazione.get(position)); 
          myIntent.putExtra("immagine", array_image2[position]); 
          myIntent.putExtra("formulaConvertita", formulaConvertita.get(position)); 
          myIntent.putExtra("note", note.get(position)); 
          startActivityForResult(myIntent, 0); 
         } 

         } 
       ); 
     } 
     } 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getSupportMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

class ListViewItem { 
public int ThumbnailResource; 
public String Title; 
public String SubTitle; 
} 
} 

這裏是我的代碼沒有的AsyncTask:

public class MostraTutti extends SherlockActivity { 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.mostra_tutti); 
    getSupportActionBar().setDisplayShowHomeEnabled(false); 

    final ListView lv = (ListView) findViewById(R.id.listView); 
    final List<ListViewItem> items = new ArrayList<MostraTutti.ListViewItem>(); 
    final ArrayList<String> nome = new ArrayList<String>(); 
    final ArrayList<String> immagine = new ArrayList<String>(); 
    ... 

    final int array_image2[] ={R.drawable.iodocloroidrossichinolina,R.drawable.acidoacetilsalicilico, 
      ...}; 

的InputStream XMLFILE = getResources()openRawResource(R.raw.sostanze);

try { 

     DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 
     final Document document = documentBuilder.parse(xmlFile); 
     document.getDocumentElement().normalize(); 
     //tagHandler.handleChannelTag(document); 
     NodeList nodeList = document.getElementsByTagName("sostanza"); 

     for (int i = 0; i < nodeList.getLength(); i++) { 
     final int indice = i; 

     nome.add(document.getElementsByTagName("nome").item(indice).getTextContent()); 
     iupac.add(document.getElementsByTagName("iupac").item(indice).getTextContent()); 
     aspetto.add(document.getElementsByTagName("aspetto").item(indice).getTextContent()); 
     formula.add(document.getElementsByTagName("formula").item(indice).getTextContent()); 
     immagine.add(document.getElementsByTagName("immagine").item(indice).getTextContent()); 
     appartenenza.add(document.getElementsByTagName("appartenenza").item(indice).getTextContent()); 
     spiegazione.add(document.getElementsByTagName("spiegazione").item(indice).getTextContent()); 
     tempFus.add(document.getElementsByTagName("temperaturaFusione").item(indice).getTextContent()); 
     tempEboll.add(document.getElementsByTagName("temperaturaEbollizione").item(indice).getTextContent()); 
     solubilita.add(document.getElementsByTagName("solubilita").item(indice).getTextContent()); 
     note.add(document.getElementsByTagName("eccezioni").item(indice).getTextContent()); 

     String str = document.getElementsByTagName("formula").item(indice).getTextContent(); 

     str = str.replaceAll("0", "\u2080"); 
     str = str.replaceAll("1", "\u2081"); 
     str = str.replaceAll("2", "\u2082"); 
     str = str.replaceAll("3", "\u2083"); 
     str = str.replaceAll("4", "\u2084"); 
     str = str.replaceAll("5", "\u2085"); 
     str = str.replaceAll("6", "\u2086"); 
     str = str.replaceAll("7", "\u2087"); 
     str = str.replaceAll("8", "\u2088"); 
     str = str.replaceAll("9", "\u2089"); 

     final String stringa = str; 
     formulaConvertita.add(stringa); 

     items.add(new ListViewItem() 
      {{ 
       ThumbnailResource = array_image2[indice]; 
       Title = document.getElementsByTagName("nome").item(indice).getTextContent(); 
       SubTitle = stringa; 
      }}); 
     } 
    } catch (IOException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } catch (ParserConfigurationException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (SAXException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }  
    CustomListViewAdapter adapter = new CustomListViewAdapter(this,items); 
    lv.setAdapter(adapter); 

    lv.setOnItemClickListener(
      new OnItemClickListener() 
      { 
       public void onItemClick(AdapterView<?> arg0, View v, int position, long id) 
       {       
        Context context = getBaseContext(); 
        Intent myIntent = new Intent(context, Dettagli.class); 

        myIntent.putExtra("nome_sostanza",nome.get(position)); 
       // myIntent.putExtra("formula",formula.get(position)); 
        myIntent.putExtra("iupac",iupac.get(position));     
        myIntent.putExtra("aspetto",aspetto.get(position));     
        myIntent.putExtra("appartenenza",appartenenza.get(position)); 
        myIntent.putExtra("solubilita",solubilita.get(position)); 
        myIntent.putExtra("tempFus",tempFus.get(position)); 
        myIntent.putExtra("tempEboll",tempEboll.get(position)); 
        myIntent.putExtra("spiegazione",spiegazione.get(position)); 
        myIntent.putExtra("immagine", array_image2[position]); 
        myIntent.putExtra("formulaConvertita", formulaConvertita.get(position)); 
        myIntent.putExtra("note", note.get(position)); 
        startActivityForResult(myIntent, 0); 
       } 

       } 
     ); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getSupportMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

class ListViewItem { 
public int ThumbnailResource; 
public String Title; 
public String SubTitle; 
} 
} 

模擬器上的區別是主線程爲16秒,AsyncTask爲1分鐘!

+0

是。這是你需要的。 http://stackoverflow.com/a/14217816/1856738 – 2013-04-25 11:09:02

回答

2

我已經將此問題標記爲重複項,但上次我做到了這一點,審閱者投了反對票。

無論哪種方式,其原因是AsyncTaskdoInBackground()運行在一個研究背景優先級和具有在CPU時間與所有其它後臺任務,最多10%共享,如您的RSS閱讀器的等等 - 無論多麼閒置系統真的是。

對於detailed discussion and solution, see here

0

UI線程上的16秒仍然過多,這不是一個解決方案 - 您的用戶每次都會被ANR對話框命中。因此,一些建議是:

  1. 優化doInBackground()中的代碼。
  2. 考慮使用另一個XML解析器,它可能會提高性能。
  3. 如果適合您的應用程序邏輯,請將此代碼移到後臺Service以使其在用戶未與應用程序交互時處理數據。將信息存儲在數據庫中,並在打開Activity時加載它。