|
안드로이드(Android) RSS 구현4 - RSS 피드 구현 제목,타이틀등 상세 구현 |
|
환경 : Eclipse Mars, Android 4.2.2 |
이번예제는 이전 RSS 리스트 구현에서 좀더 업그레이드 된 버전 입니다. 이전에는 RSS 제목들만 가져왔는데 이번에는 RSS 객체의 각 요소들에 대한 값들을 관리하는 VO(Value Object) RssItem 과 Feed 에 대한 설정값을 셋팅하는 RssFeed VO, 접속해서 값을 가져오고 가공하는 RssHandler 3개로 분리 하였습니다.
▼ 먼저 메인에서 사용한 내용에 대해 언급합니다. 아래에서 언급할 RssHandler 객체를 만들고 getFeed() 함수를 호출해 RssFeed 객체를 리턴 받습니다. 이곳에 RSS 호출한 정보다 모두 담겨 있게 됩니다.
RssHandler myRSSHandler = new RssHandler(); myXMLReader.setContentHandler(myRSSHandler); InputSource myInputSource = new InputSource(rssUrl.openStream()); myXMLReader.parse(myInputSource); mRssFeed = myRSSHandler.getFeed();
▼ 이렇게 getFeed() 로 리턴받은 RssFeed 객체의 각 함수들을 호출하여 메인 화면을 채웁니다. 함수명에서 알수 있듯 getTitle() 은 제목이며 getDescription() 은 RSS 전체 제목입니다. 그리고 getList() 를 호출하여 RssItem 리스트를 리턴받아 ArrayAdapter 에 셋팅합니다. 그러면 메인화면에서 리스트가 구현이 되겠죠.
private void setListView(){
TextView feedTitle = (TextView)findViewById(R.id.feedtitle);
TextView feedDescribtion = (TextView)findViewById(R.id.feeddescribtion);
TextView feedPubdate = (TextView)findViewById(R.id.feedpubdate);
TextView feedLink = (TextView)findViewById(R.id.feedlink);
feedTitle.setText(mRssFeed.getTitle());
feedDescribtion.setText(mRssFeed.getDescription());
feedPubdate.setText(mRssFeed.getPubdate());
feedLink.setText(mRssFeed.getLink());
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(
this,
android.R.layout.simple_list_item_1,
mRssFeed.getList());
setListAdapter(adapter);
}
▼ 메인 activity 를 구성하기 위한 레이아웃 xml 전체 내용입니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="RSS 피드 상세 구현" />
<TextView
android:id="@+id/feedtitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/feeddescribtion"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/feedpubdate"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/feedlink"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:autoLink="web" />
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@android:id/empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="No Data" />
</LinearLayout>
▼ 메인 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.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import android.app.ListActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class XmlRssInfoActivity extends ListActivity {
private RssFeed mRssFeed = null;
private TextView mResult;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xml_rss_info);
ProcessXmlTask xmlTask = new ProcessXmlTask();
xmlTask.execute("http://mainia.tistory.com/rss");
}
private void setListView(){
TextView feedTitle = (TextView)findViewById(R.id.feedtitle);
TextView feedDescribtion = (TextView)findViewById(R.id.feeddescribtion);
TextView feedPubdate = (TextView)findViewById(R.id.feedpubdate);
TextView feedLink = (TextView)findViewById(R.id.feedlink);
feedTitle.setText(mRssFeed.getTitle());
feedDescribtion.setText(mRssFeed.getDescription());
feedPubdate.setText(mRssFeed.getPubdate());
feedLink.setText(mRssFeed.getLink());
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(
this,
android.R.layout.simple_list_item_1,
mRssFeed.getList());
setListAdapter(adapter);
}
// 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);
mRssFeed = myRSSHandler.getFeed();
} 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) {
setListView();
super.onPostExecute(result);
}
}
}
▼ 이제 VO 객체인 RssFeed 와 RssItem 에 대한 설명입니다. 먼저 RssFeed 인데 RSS 전체 정보에 대한 내용이 저장되며 각 RSS 아티클이 저장되는 RssItem 은 addItem() 함수를 통해 Vector 에 저장됩니다. 꺼낼때는 getList() 를 호출합니다.
import java.util.List;
import java.util.Vector;
public class RssFeed {
private String title = null;
private String description = null;
private String link = null;
private String pubdate = null;
private List<RssItem> itemList;
RssFeed() {
itemList = new Vector<RssItem>(0);
}
void addItem(RssItem item) {
itemList.add(item);
}
RssItem getItem(int location) {
return itemList.get(location);
}
List<RssItem> getList() {
return itemList;
}
void setTitle(String value) {
title = value;
}
void setDescription(String value) {
description = value;
}
void setLink(String value) {
link = value;
}
void setPubdate(String value) {
pubdate = value;
}
String getTitle() {
return title;
}
String getDescription() {
return description;
}
String getLink() {
return link;
}
String getPubdate() {
return pubdate;
}
}
▼ 두번째 VO 객체인 RssItem 입니다. 이곳에는 각 행에 해당하는 아티클에 대한 정보들이 저장되겠죠. 글제목, 글 내용, 발행일자등등 이 저장되는 VO 입니다. 이 값들을 List 객체에 추가해 메인화면에서 리스트를 구성하는 것이죠.
public class RssItem {
private String title = null;
private String description = null;
private String link = null;
private String pubdate = null;
RssItem() {
}
void setTitle(String value) {
title = value;
}
void setDescription(String value) {
description = value;
}
void setLink(String value) {
link = value;
}
void setPubdate(String value) {
pubdate = value;
}
String getTitle() {
return title;
}
String getDescription() {
return description;
}
String getLink() {
return link;
}
String getPubdate() {
return pubdate;
}
@Override
public String toString() {
return title;
}
}
▼ 다음은 RSS XML 값들을 파싱해서 VO 객체에 셋팅하는 역할을 하는 RssHandler 입니다. SAX API 인 DefaultHandler 를 상속받아 만들었으며 Characters() 함수에서 요소에 값이 무엇인지 판단하여 VO 에 셋팅합니다.
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class RssHandler extends DefaultHandler {
final int STATE_UNKNOW = 0;
final int STATE_TITLE = 1;
final int STATE_DESCRIPTION = 2;
final int STATE_LINK = 3;
final int STATE_PUBDATE = 4;
int currentState = STATE_UNKNOW;
RssFeed feed;
RssItem item;
boolean itemFound = false;
RssHandler() {
}
RssFeed getFeed() {
return feed;
}
@Override
public void startDocument() throws SAXException {
feed = new RssFeed();
item = new RssItem();
}
@Override
public void endDocument() throws SAXException {
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (localName.equalsIgnoreCase("item")) {
itemFound = true;
item = new RssItem();
currentState = STATE_UNKNOW;
} else if (localName.equalsIgnoreCase("title")) {
currentState = STATE_TITLE;
} else if (localName.equalsIgnoreCase("description")) {
currentState = STATE_DESCRIPTION;
} else if (localName.equalsIgnoreCase("link")) {
currentState = STATE_LINK;
} else if (localName.equalsIgnoreCase("pubdate")) {
currentState = STATE_PUBDATE;
} else {
currentState = STATE_UNKNOW;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (localName.equalsIgnoreCase("item")) {
feed.addItem(item);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String strCharacters = new String(ch, start, length);
if (itemFound == true) {
// "item" tag found, it's item's parameter
switch (currentState) {
case STATE_TITLE:
item.setTitle(strCharacters);
break;
case STATE_DESCRIPTION:
item.setDescription(strCharacters);
break;
case STATE_LINK:
item.setLink(strCharacters);
break;
case STATE_PUBDATE:
item.setPubdate(strCharacters);
break;
default:
break;
}
} else {
// not "item" tag found, it's feed's parameter
switch (currentState) {
case STATE_TITLE:
feed.setTitle(strCharacters);
break;
case STATE_DESCRIPTION:
feed.setDescription(strCharacters);
break;
case STATE_LINK:
feed.setLink(strCharacters);
break;
case STATE_PUBDATE:
feed.setPubdate(strCharacters);
break;
default:
break;
}
}
currentState = STATE_UNKNOW;
}
}
'안드로이드 개발' 카테고리의 다른 글
| 안드로이드(Android) 경고 - Custom view… overrides onTouchEvent but not performClick (0) | 2014.11.28 |
|---|---|
| 안드로이드(Android) onDraw 함수를 이용해 화면에 비트맵이미지, 도형 그리기 (0) | 2014.11.27 |
| 안드로이드(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 구현3 - RSS 피드 읽어서 ListView 로 제목 표현하기 (0) | 2014.11.23 |
| 안드로이드(Android) RSS 구현2 - XML 파싱클래스를 이용해서 RSS Reader 구현하기 (5) | 2014.11.22 |
| 안드로이드(Android) RSS 구현1 - XmlResourceParser 를 이용하여 XML 파싱하기 (0) | 2014.11.21 |
| 안드로이드(Android) Java 코드에서 색깔값 화면에 입히기 (0) | 2014.11.20 |
