【问题标题】:the application says not responding, even after i used AsyncTask to relieve the load on the main thread应用程序说没有响应,即使我使用 AsyncTask 来减轻主线程上的负载
【发布时间】:2012-07-24 04:53:23
【问题描述】:

此代码解析本地存储的 xml 文件,然后从解析的数据创建动态 UI,尽管我还没有完成 UI 部分。昨天还好好的,现在突然没反应了。

public class XML_PARSER extends Activity {

String TAG= "XML_PARSER";
List optionList = new ArrayList(); ;
Document dom;
Document doc;
Menu mymenu=null;

String msg=null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.parser);
    new ParseXML().execute();
   }

private class ParseXML extends AsyncTask<Integer, Integer, Document>{
    @Override
protected Document doInBackground(Integer... params) {

     DocumentBuilderFactory dbf= DocumentBuilderFactory.newInstance();
    Document dom1=null;
    try {
        //Uri uri = Uri.parse("android.resource://com.example.xml_parser/raw/options");
        InputStream is=getResources().openRawResource(R.raw.options);

        DocumentBuilder db = dbf.newDocumentBuilder();
        dom1=db.parse(is);
        Log.i(TAG,"parsing done");

    }

    catch(ParserConfigurationException pce){
        pce.printStackTrace();
    }
    catch(SAXException se){
        se.printStackTrace();
    }
    catch(IOException ioe){
        ioe.printStackTrace();
    }
    return dom1;

}
    @Override
    public void onPostExecute(Document d) {
        ParseDocument(d); 
        //onCreateOptionsMenu(mymenu);
        text();
        }



}
@SuppressWarnings("unchecked")
public void ParseDocument(Document dom){
    Element docEle = dom.getDocumentElement();
    Node node;

    NodeList n1= docEle.getElementsByTagName("Option");
    if(n1!=null && n1.getLength()>0){

        for(int i=0;i<n1.getLength();i++){

            node=n1.item(i);

            Element e1=(Element)n1.item(i);

它会以某种方式卡在这个 getOption() 上,因为如果写在下面,则不会打印日志,而如果写在上面,则会打印日志。

            Option e = getOption(e1,node);
            Log.i(TAG,"Parse Document reached");

            optionList.add(e);



            }

        }

    }

private Option getOption(Element el,Node parent){

    String name= getTextValue(el,"Name");
    String type = el.getAttribute("type");


    Option op = new Option(name,type);
    fillSubOptions(op, el, parent);

    return op;


}

private String getTextValue(Element ele, String tagName){
    String textVal=null;
    NodeList n1 = ele.getElementsByTagName(tagName);

    if(n1!=null && n1.getLength()>0){
        Element el= (Element)n1.item(0);
        textVal =el.getFirstChild().getNodeValue();

    }
    return textVal;
}


private void fillSubOptions(Option op, Element el, Node parent){
    Element ele;
    Node node;
    String name = null;
    NodeList n1 = el.getElementsByTagName("Option");
    int count =0;
    if(n1!=null && n1.getLength()>0){
        for(int i=0;i<n1.getLength();i++){
            ele = (Element)n1.item(i);
            node= n1.item(i);
            if((node.getParentNode()).equals(parent)){
                name= getTextValue(ele, "Name");
                count= op.printSubOptions(count);
                op.setSubOptions(name);
            }
        }
    }

}




@SuppressWarnings("unchecked")
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    this.mymenu=menu;
    Iterator<Option> it= optionList.iterator();
    int count=0;
    while(it.hasNext()){
        Option e= (Option)it.next();
        if(e.getType().equals("menu")){
            count++;
            menu.add(0,count,0,e.getName());
        }
    }


    getMenuInflater().inflate(R.menu.parser, menu);
    return true;
}




public class Option {


    String name;
    String type;
    String parent;
    int count;
    ArrayList<String> subOptions;
    Option(String name,String type)
    {
        setName(name);
        setType(type);

        subOptions = new ArrayList<String>();
        parent = null;
    }
    public void setName(String name) {
        this.name = name;
    }

    public void setType(String type) {
        this.type = type;
    }
    public void setSubOptions(String subOption) {
        (this.subOptions).add(subOption);

    }

    public String getName() {
        return name;
    }
    public int printSubOptions(int count) {
        Iterator<String> it = (this.subOptions).iterator();
        if(it.hasNext()){

            while(it.hasNext()){

                count++;
            }
        }
        return count;


    }
    public String getType() {
        return type;

}


}

【问题讨论】:

  • 如果您的目的是从解析的 xml 制作 UI,为什么还要在那里使用 AsyncTask?
  • 对于问题本身,您可以通过在getOption、fullSubOptions等中一路添加cmets或使用断点调试来轻松找到问题。
  • 您检查过 ANR 日志文件吗?
  • @niko-i 首先解析 xml 文件,同时在同一个线程中解析和创建 UI 使我的应用程序无响应,这就是 AsyncTak() 的原因
  • @YellowJK- 你能告诉我怎么做吗?

标签: java android xml xml-parsing


【解决方案1】:

由于onPostExecuted中调用的方法获得了UI线程的控制权,我希望这可能是你正在做的解析仍然存在的原因在 UI 线程 上完成,因此您的 应用程序停止响应,因为它将是 parsing 数据。

使用 onPreExecute() 像这样启动ProgressDialog。在顶部声明ProgressDialog Globally

ProgressDialog pd;

onPreExecute 方法中启动它。

 @Override
    public void onPreExecute() {
          pd=ProgressDialog.show(myActivity.this,"","Please Wait");
        }

doInBackground 中调用这两个方法本身在底部。不要在 PostExecute 方法中调用它,以便它在 BackGround 中获得executed

ParseDocument(d); 
text();

现在,在 PostExecute 方法中,关闭 progressDialog。

@Override
    public void onPostExecute(Document d) {
          pd.dismiss();  //Dismiss the Progress Dialog 
        }

【讨论】:

  • 当我在 doInBackground() 中调用我的 ParseDocument() 方法时,它说的是无法访问的代码..
  • 不要继续返回dom1;在返回语句之前,调用 ParseDocument() 和 text()。从 doInBackground() 中返回 null 并且 ParseDocument() 应该在返回值之前被调用。我希望你可能会返回值然后调用 ParseDocument() 方法。
  • 哦..我很抱歉语法问题...使用这种方式..我将编辑我的答案..pd=ProgressDialog.show(XML_PARSER.this,"","请稍候" );
  • 我已经知道了,但是进度对话框不走,卡在了,请稍候。并且 logcat 显示“应用程序可能在主线程上做了太多工作”......它只是跳帧。
  • 当任何方法从 doInBackground() 更新你的 UI 时,你必须在 doInBackground() 中使用这个方法来更新它。 runOnUI()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多