如何为SAX解析器设置线程和处理程序?

时间:2011-10-03 01:18:46

标签: android sax android-ui

我一直在尝试为SAX解析器设置UI线程和处理程序。这是我的解析器没有实现UI线程和处理程序:

public class AndroidXMLReader extends ListActivity {

    private XMLFeed myXMLFeed = null;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
            try {
                URL xmlUrl = new URL("http://feeds.bbci.co.uk/news/uk/rss.xml");
                SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
                SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
                XMLReader myXMLReader = mySAXParser.getXMLReader();
                XMLHandler myXMLHandler = new XMLHandler();
                myXMLReader.setContentHandler(myXMLHandler);
                InputSource myInputSource = new InputSource(xmlUrl.openStream());
                myXMLReader.parse(myInputSource);

                myXMLFeed = myXMLHandler.getFeed();

            }

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

        if (myXMLFeed!=null)
        {
            ArrayAdapter<XMLItem> adapter =
             new ArrayAdapter<XMLItem>(this,
               android.R.layout.simple_list_item_1,myXMLFeed.getList());
            setListAdapter(adapter);
        }
        }
    }

然后在这里我去尝试添加UI线程&amp;处理程序。 编辑1 - 根据HellBoy的回复,这是修改后的代码:

   public class AndroidXMLReader extends ListActivity {

    private static final int THREAD_FINISHED = 0;
    private XMLFeed myXMLFeed = null;
    private ProgressDialog progressDialog;
    private Button refreshFeed;
    Handler handler = new Handler();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        initControls();
    }

    public void initControls(){


          refreshFeed = (Button) findViewById(R.id.refresh);

          refreshFeed.setOnClickListener(new Button.OnClickListener(){
              @Override
              public void onClick(View v){
                  progressDialog = ProgressDialog.show(AndroidXMLReader.this, "",
                            "Please wait for few seconds...", true);
                  processThread();          
              }
          });
    }
    protected void processThread() {
        Thread t = new Thread()
        {
            public void run(){
                 getNews();
                 //UI();
                 // Sends message to the handler so it updates the UI
                 handler.sendMessage(Message.obtain(mHandler, THREAD_FINISHED));

                 ; }
        };
        t.start();
    }

    private Handler mHandler = new Handler() {
        @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);

                switch (msg.what) {
                case THREAD_FINISHED:

                           progressDialog.dismiss();
                           break;    
                    };

            };
    };

    private void getNews(){
        try {
            URL xmlUrl = new URL("http://feeds.bbci.co.uk/news/uk/rss.xml");
            SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
            SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
            XMLReader myXMLReader = mySAXParser.getXMLReader();
            XMLHandler myXMLHandler = new XMLHandler();
            myXMLReader.setContentHandler(myXMLHandler);
            InputSource myInputSource = new InputSource(xmlUrl.openStream());
            myXMLReader.parse(myInputSource);

            myXMLFeed = myXMLHandler.getFeed();

        }

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

        if (myXMLFeed!=null){
            ArrayAdapter<XMLItem> adapter =
                 new ArrayAdapter<XMLItem>(this,
                   android.R.layout.simple_list_item_1,myXMLFeed.getList());
                setListAdapter(adapter);
        }

    }
}

目前它挂在进度对话框中,我无法弄清楚为什么......任何帮助都将不胜感激。

编辑1 - 我现在收到的错误消息是:

  

只有创建视图层次结构的原始线程才能触及它   视图。

    10-04 21:39:27.570: ERROR/AndroidRuntime(17454):     at com.android.testfeed3.AndroidXMLReader.getNews(AndroidXMLReader.java:121)
10-04 21:39:27.570: ERROR/AndroidRuntime(17454):     at com.android.testfeed3.AndroidXMLReader.access$2(AndroidXMLReader.java:85)
10-04 21:39:27.570: ERROR/AndroidRuntime(17454):     at com.android.testfeed3.AndroidXMLReader$3.run(AndroidXMLReader.java:60)
10-04 21:39:27.645: WARN/ActivityManager(2703):   Force finishing activity com.android.testfeed3/.AndroidXMLReader
10-04 21:39:33.495: ERROR/WindowManager(17454): Activity com.android.testfeed3.AndroidXMLReader has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40527a20 that was originally added here
10-04 21:39:33.495: ERROR/WindowManager(17454): android.view.WindowLeaked: Activity com.android.testfeed3.AndroidXMLReader has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40527a20 that was originally added here
10-04 21:39:33.495: ERROR/WindowManager(17454):     at com.android.testfeed3.AndroidXMLReader$2.onClick(AndroidXMLReader.java:50)

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:1)

尝试将您的processThread()方法设为这样

protected void processThread() {
    Thread t = new Thread()
    {
        public void run() {
            theThread();}

    };
    t.start();
}

答案 1 :(得分:1)

为了对UI进行更改,命令必须来自创建它的线程,即主(或UI)线程。

快速浏览一下,这一行:

if (myXMLFeed!=null)
{
   ArrayAdapter<XMLItem> adapter =
    new ArrayAdapter<XMLItem>(this,
      android.R.layout.simple_list_item_1,myXMLFeed.getList());
   setListAdapter(adapter);
}

需要放在一个单独的Handler中,Handler从你的新线程中调用。

答案 2 :(得分:0)

只需扫描您的代码,但我没有看到任何问题。您可以放置​​一些调试日志以查看哪条线卡住了。但如果我是你,我会使用AsynTask。

当您想要从后台线程更新UI时,线程和处理程序会派上用场。 当您触发阻止UI的内容时,将使用AsynTask。

在你的情况下,我认为AsynTask更好。

1)Android Doc of AsynTask

2)使用onPreExecute()(UI线程)来启动你想要的pregress对话框

3)在doInBackground()(工作线程)中进行实际的URL和SAX解析。这将在后台线程中为您运行代码,因此您不必初始化它。

4)onPostExecute()(UI线程),关闭对话框或执行任何想要更新UI的操作。

答案 3 :(得分:0)

等待!!这可能是什么?

    protected void processThread() {
    Thread t = new Thread();{ <--- a semi-colon

你可能想在线程't'中再次检查你的逻辑。