공지사항을 다 읽었음
여기서의 파서라는건 프로그램이라기 보다는.. 라이브러리 함수죠..
웹에서 사용하는 언어와 프로그래밍 언어가 다르기때문에 웹의 html언어나 xml언어를 그대로 사용할수 없습니다.
그래서 이 다른 언어를 분석하여 필요한 데이터만 뽑아올수있게 도와주는게 파서입니다.
따라서 이 파서라는것도 종류가 한가지가 아닙니다.
xml문서를 파싱하는 파서도 DOM파서나 SAX 파서 등이 존재하고.. html문서를 파싱하는 파서도 여러가지가 있습니다.
파서의 경우 안드로이드 프로젝트에서 바로 사용할수 있는 파서도 있고 유명한 html파서중 제리코 파서라고 있는데 이러한건 공개된 라이브러리이므로 다운받으셔서 사용할수도 있습니다.
그리고 웹과 관련된 경우라면 어떠한 경우든 쓰레드는 필수라고 생각됩니다.
다운받는 속도가 순식간에 이루어지는게 아니라면 어떠한 경우는 딜레이가 생깁니다. 쓰레드를 사용하지 않으면 메인 쓰레드에서 다운로드가 끝날때까지 기다리게 되는데 이때 사용자는 마치 핸드폰이 다운된듯한 느낌을 받습니다. 버튼이나 기타 아무것도 작동을 할수 없거든요..
따라서 이러한 기다림을 최소화(?)가 아니라 다운된듯한 느낌을 못받게 하기 위해.. 적어도 다운받는동안 로딩화면을 보여준다거나 프로그래스바를 띄어주지요..
쓰레드는 필수적으로 공부해야 되는 부분입니다.. 자바책이나 안드로이드 책 보셔야 할듯합니다..
아 혹시나 해서 그러는데.. 쓰레드는 하나의 작업을 수행할수 있는 능력?? 으로 생각하면 될듯합니다..
예를 들어 1+1을 하는 연산과 2+2를 하는 연산이 있을시에.. 단일쓰레드라면 1+1을 먼저하고 2+2를 수행합니다만..
멀티쓰레드라면.. 1+1과 2+2를 각각 수행합니다.
보통 액티비티 하나 만들고 실행되는건 메인쓰레드에서 실행됩니다. 즉 단일쓰레드 하나만 돌아갑니다..
따라서 다운로드를 메인쓰레드에서만 하게 된다면.. 다운로드가 끝날때까지 아무동작도 못하는겁니다..
하나의 쓰레드를 더 만들어 다운받는 행위를 그 쓰레드에서 수행하게 되면.. 메인쓰레드는 사용자의 입력이나 다른 작업을 계속 받을수 있기때문에 다른 동작을 할 수 있습니다.




이런 예제 구글에 널리고 널렸지만 그냥 한번 올려 봅니다.
xml은 아시죠? 파서라는게 있는지 없는진 모르겠는데
기본적으로 XmlPullParserFactory와 XmlPullParser를 사용합니다.
전혀 모르신다고 하시니 주석까지 달아 드렸습니다.
(당연히 스레드 또는 AsyncTask 안에서 처리하셔야 합니다. 자세한건 개발자 사이트 참조)
URL url = new URL(PAGE + path); // 파싱해올 url
XmlPullParserFactory xpp = XmlPullParserFactory.newInstance();
XmlPullParser parser = xpp.newPullParser();
parser.setInput(url.openStream(), CHARACTER_SET); // 위의 url로부터 스트림을 생성
String tag = "", text = ""; // 태그와 내용 초기화
if (map.size() > 0) map.clear(); // 여러번 호출시 데이터 중복을 방지하기 위해 arraylist 초기화
Map<String, CharSequence> product = new HashMap<String, CharSequence>();
// xml에서 item 하나가 들어갈 해시맵
while (parser.next() != XmlPullParser.END_DOCUMENT) { // xml이 끝날때까지 반복
switch (parser.getEventType()) { // 현재 무엇을 파싱하고 있는지를 검사
case XmlPullParser.START_TAG: // 태그를 만났을 경우
tag = parser.getName(); // 변수에 태그명을 대입
if (ITEM.equalsIgnoreCase(tag)) { // 새로운 item이 시작되었으므로 새로운 해시맵 생성
product = new HashMap<String, CharSequence>(); }
break;
case XmlPullParser.TEXT: // 태그 내부의 내용을 만났을 경우
text = parser.getText(); // 변수에 해당 내용을 대입
for (int i = 0; i < TAGS.length; i++) {
if (TAGS[i].equalsIgnoreCase(tag)) { // 내용이 속한 태그를 검사
product.put(TAGS[i], text); }} // 해당 태그가 있으면 해시맵에 데이터를 넣음
break;
case XmlPullParser.END_TAG: // 태그가 끝났을 경우
tag = parser.getName();
if (ITEM.equalsIgnoreCase(tag)) { // item 하나가 끝났으므로 arraylist에 추가
map.add(product);
product = null; }
tag = ""; text = ""; // 중복 방지를 위해 태그와 내용 초기화
break; }}
대충 기본형은 이렇습니다. 이왕이면 클래스 하나 따로 만들어서 구조체랑 같이 쓰시는게 편하실 겁니다.
태그랑 내용을 구분해서
태그와 내용을 쌍으로 하는 해시맵 객체 1개당
xml의 item1개 단위로 해서 이걸 모은 arraylist를 만들고
이걸 액티비티에서 리턴받아서 지지고 볶고 하면 됩니다.
가운데 for문 들어간건 파싱해야할 태그가 많아질 경우
태그들을 구조체에 배열로 선언하여 코드가 길어지는걸 방지하기 위해서인데
별로 좋은 방법은 아닙니다. 전 귀찮아서 이렇게 만들었지만
성능을 생각하신다면 일일이 태그로 다 비교하셔야 합니다.