Please Enable JavaScript!
Gon[ Enable JavaScript ]

안드로이드(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) RSS 구현4 - RSS 피드 구현 제목,타이틀등 상세 구현

 

Posted by 녹두장군

댓글을 달아 주세요