안드로이드(Android) RSS 구현2 - XML 파싱클래스를 이용 RSS Reader 구현하기 |
개발환경 : Eclipse Mars, Android 4.2.2 |
이전에 작성했던 XML 파싱 클래스 예제에서 조금 더 확장하여 RSS XML 을 읽어와서 화면에 표현해 보도록 합니다. 이번 사용한 API 는 Android SAX API 입니다. SAX 는 XML 을 분석할수 있는 심플한 API 이며 원래 java 용으로 만들었습니다.
▼ 샘플 앱을 실행한 화면입니다. 왼쪽은 브라우저에서 RSS 주소로 들어가 데이터를 긁어 온 것이고 오른쪽은 앱을 실행해서 현재 12개의 데이터를 가져왔는데 제목만 표시 하였습니다.
▼ 먼저 환경설정을 해야 합니다. 인터넷을 접속해서 데이터를 가져와야 하기 때문에 AndroidManifest.xml 에 INTERNET 퍼미션을 셋팅합니다.
<uses-permission android:name="android.permission.INTERNET" />
▼ 다음은 메인 activity 에 xml 값을 가져오기 위해 AsyncTask 상속받아 ProcessXmlTask 클래스를 만듭니다. 인수로 RSS 피드값을 읽어올 주소를 넘깁니다.
ProcessXmlTask xmlTask = new ProcessXmlTask(); xmlTask.execute("http://mainia.tistory.com/rss");
▼ 만든 클래스에 doInBackground() 함수를 구현합니다. 이곳에 XML 값을 가져와서 파싱하는 코드가 들어갑니다.
protected Void doInBackground(String... urls) { try { URL rssUrl = new URL(urls[0]); SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance(); SAXParser mySAXParser = mySAXParserFactory.newSAXParser(); XMLReader myXMLReader = mySAXParser.getXMLReader(); RSSHandler myRSSHandler = new RSSHandler(); myXMLReader.setContentHandler(myRSSHandler); InputSource myInputSource = new InputSource(rssUrl.openStream()); myXMLReader.parse(myInputSource); } catch (MalformedURLException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } catch (ParserConfigurationException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } catch (SAXException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } catch (IOException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } return null; }
▼ 그리고 ProcessXmlTask 객체에서 결과값을 TextView 에 셋팅해야 하는데 onPostExecute() 함수를 오버라이딩해서 처리 합니다. doInBackground() 하면 Thread 에러 납니다. onPostExecute() 함수는 스레드가 종료되면 끝에 실행되는 함수입니다.
@Override protected void onPostExecute(Void result) { mResult.setText(streamTitle); super.onPostExecute(result); }
▼ 다음은 SAX API 의 DefaultHandler 을 상속받아 만든 RSSHandler 입니다. 상속하게 되면 필수로 구현해야 되는 함수들이 있는데 startDocument, endDocument, startElemnet, endElement, characters 등이 있습니다. 함수명에서 알수 있듯이 xml 문서가 시작되고 끝날 때, 요소가 시작될때와 종료될때함수들입니다. 이곳에서 값을 읽어와 문자열을 구성한 것입니다.
private class RSSHandler extends DefaultHandler { final int stateUnknown = 0; final int stateTitle = 1; int state = stateUnknown; int numberOfTitle = 0; String strTitle = ""; String strElement = ""; @Override public void startDocument() throws SAXException { strTitle = "--- Start Document ---\n"; } @Override public void endDocument() throws SAXException { strTitle += "--- End Document ---"; streamTitle = "Number Of Title: " + String.valueOf(numberOfTitle) + "\n" + strTitle; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (localName.equalsIgnoreCase("title")) { state = stateTitle; strElement = "Title: "; numberOfTitle++; } else { state = stateUnknown; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (localName.equalsIgnoreCase("title")) { strTitle += strElement + "\n"; } state = stateUnknown; } @Override public void characters(char[] ch, int start, int length) throws SAXException { String strCharacters = new String(ch, start, length); if (state == stateTitle) { strElement += strCharacters; } } }
▼ 레이아웃 xml 은 간단하므로 생략하도록 하겠습니다. 아래는 메인 activity 의 전체 소스입니다.
import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.widget.TextView; public class XmlSAXParserActivity extends Activity { String streamTitle = ""; private TextView mResult; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_xml_saxparser); mResult = (TextView) findViewById(R.id.result); ProcessXmlTask xmlTask = new ProcessXmlTask(); xmlTask.execute("http://mainia.tistory.com/rss"); } // AsyncTask<Params,Progress,Result> private class ProcessXmlTask extends AsyncTask<String, Void, Void> { protected Void doInBackground(String... urls) { try { URL rssUrl = new URL(urls[0]); SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance(); SAXParser mySAXParser = mySAXParserFactory.newSAXParser(); XMLReader myXMLReader = mySAXParser.getXMLReader(); RSSHandler myRSSHandler = new RSSHandler(); myXMLReader.setContentHandler(myRSSHandler); InputSource myInputSource = new InputSource(rssUrl.openStream()); myXMLReader.parse(myInputSource); } catch (MalformedURLException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } catch (ParserConfigurationException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } catch (SAXException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } catch (IOException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } return null; } @Override protected void onPostExecute(Void result) { mResult.setText(streamTitle); super.onPostExecute(result); } } private class RSSHandler extends DefaultHandler { final int stateUnknown = 0; final int stateTitle = 1; int state = stateUnknown; int numberOfTitle = 0; String strTitle = ""; String strElement = ""; @Override public void startDocument() throws SAXException { strTitle = "--- Start Document ---\n"; } @Override public void endDocument() throws SAXException { strTitle += "--- End Document ---"; streamTitle = "Number Of Title: " + String.valueOf(numberOfTitle) + "\n" + strTitle; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (localName.equalsIgnoreCase("title")) { state = stateTitle; strElement = "Title: "; numberOfTitle++; } else { state = stateUnknown; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (localName.equalsIgnoreCase("title")) { strTitle += strElement + "\n"; } state = stateUnknown; } @Override public void characters(char[] ch, int start, int length) throws SAXException { String strCharacters = new String(ch, start, length); if (state == stateTitle) { strElement += strCharacters; } } } }
'안드로이드 개발' 카테고리의 다른 글
안드로이드(Android) 코드경고 – Avoid object allocations during draw/layout operations (preallocate and reuse instead) 해제 하기 (0) | 2014.11.26 |
---|---|
안드로이드(Android) RSS 구현5 - RSS 제목별 상세내용 구현 (1) | 2014.11.25 |
안드로이드(Android) RSS 구현4 - RSS 피드 구현 제목,타이틀등 상세 구현 (0) | 2014.11.24 |
안드로이드(Android)RSS 구현3 - RSS 피드 읽어서 ListView 로 제목 표현하기 (0) | 2014.11.23 |
안드로이드(Android) RSS 구현1 - XmlResourceParser 를 이용하여 XML 파싱하기 (0) | 2014.11.21 |
안드로이드(Android) Java 코드에서 색깔값 화면에 입히기 (0) | 2014.11.20 |
안드로이드(Android) 색깔을 xml 로 정의 하고 관리하기 (0) | 2014.11.19 |
안드로이드(Android) PhoneGap, 이클립스 플러그인 설치로 좀더 쉽게 개발하기 (0) | 2014.11.18 |