'2010/07'에 해당되는 글 11건

  1. 2010.07.18 Http Client로 트위터 API 사용 by 응큼미소
  2. 2010.07.09 트위터 home_time_line by 응큼미소
  3. 2010.07.09 XML Pull Parse by 응큼미소 (2)
  4. 2010.07.08 트위터 어플개발의 시작 by 응큼미소
  5. 2010.07.07 쓰레드와 에니메이션 by 응큼미소
  6. 2010.07.03 데이터 저장 기초 by 응큼미소
  7. 2010.07.03 메뉴 by 응큼미소
  8. 2010.07.02 사용자인터페이스_02 by 응큼미소
  9. 2010.07.01 사용자인터페이스_02 by 응큼미소
  10. 2010.07.01 어플리케이션 구조 by 응큼미소

다이얼로그를 띄어서 입력하는 예제에요.












트위터 API인 Home_Time_Line 을 이용해서 List를 가져오는 예제 입니다.



























신고

'T아카데미' 카테고리의 다른 글

Http Client로 트위터 API 사용  (0) 2010.07.18
트위터 home_time_line  (0) 2010.07.09
XML Pull Parse  (2) 2010.07.09
트위터 어플개발의 시작  (0) 2010.07.08
쓰레드와 에니메이션  (0) 2010.07.07
데이터 저장 기초  (0) 2010.07.03
Posted by 응큼미소
 URL주소를 이용해서 실제로 home_time_line.xml 파일을 받아왔어요.
 tiwtter에 직접 연결해서 데이터를 가져와야 하는데요 HttpClient 클래스를 이용해서 http내에 모든걸 커스터마이징 할 수 있죠. 좀 복잡하긴 해요. URL은 기본적으로 있어야 하고요 메소드를 지정할 수도 있어요. 주로 get과 post를 지정하죠. HttpGet이용하면 get을 쓰겠다는 거에요. 실제 접속할 때는 execute를 실행을 하죠. 여기서 서버의 응답으로 response가 반환이 되요. http의 행동에는 request와 response 두가지가 있는데 응답코드로 200이 오면 연결이 잘 된거고 404가 오면 not found 한거죠. API문서에도 응답코드와 데이터에 대한 정보가 들어있어요. 그걸보고 우리는 사용하면 되죠.















List에 아이템이 생길 때 마다 매번 이미지를 다운로드 했기 때문에 스크롤이 느려졌는데요
최적화를 한번 해봤어요. 그 전에 이미지가 URL로 왔는데 어떻게 화면에 표시할 건지 궁금한데요. Bitmap은 pixel들의 배열이에요. 최적화를 위해서 이미지 배열의 공간을 최대한 가볍게 할 필요가 있죠. 안드로이드에서는 비트맵을 만들수 있는 클래스를 제공해요. 그림은 1.5M 이런식으로 저장하는게 아니라 압축을 해서 저장하죠. JPEG같은건 비트맵을 압축한 거에요. BitmapFactory는 비트맵을 압축하거나 decoding하는 클래스이죠. 안드로이드에선 JPEG보다 손실압축이 더 잘되는 PNG를 많이 써요.





XML파일에 엘리먼트로 있는 retweet때문에 파싱에 문제가 생겼는데요 한번 해결해볼께요








신고

'T아카데미' 카테고리의 다른 글

Http Client로 트위터 API 사용  (0) 2010.07.18
트위터 home_time_line  (0) 2010.07.09
XML Pull Parse  (2) 2010.07.09
트위터 어플개발의 시작  (0) 2010.07.08
쓰레드와 에니메이션  (0) 2010.07.07
데이터 저장 기초  (0) 2010.07.03
Posted by 응큼미소

XML Pull Parse

T아카데미 2010.07.09 10:11
 이번에는 XML을 파싱해 보았어요. 트위터 API를 사용하기 위한 것이죠.














이제 연습문제를 해봤어요.















신고

'T아카데미' 카테고리의 다른 글

Http Client로 트위터 API 사용  (0) 2010.07.18
트위터 home_time_line  (0) 2010.07.09
XML Pull Parse  (2) 2010.07.09
트위터 어플개발의 시작  (0) 2010.07.08
쓰레드와 에니메이션  (0) 2010.07.07
데이터 저장 기초  (0) 2010.07.03
Posted by 응큼미소
 웹서비스를 이용해서 만들어져 있는 트위터 어플이에요. 트위터 어플에는 글 올라오는걸 보고 여러가지 기능을 넣을 수 있도록
만들어야 하죠. 트위터 어플 개발 기준을 정하기 위해 기능이 많고 안정성이 좀 떨어지게 만들거나, 안정성이 좋고 기능이 좀 적게
만들건지 결정해야 해요.
 트위터 어플을 만드는 이유는요 안드로이드와 java언어가 인터넷과 연동해서 하기에 적합하기 때문이죠. 안드로이드 폰을 단순하게
게임 디바이스 용으로 쓰기에는 별로 의미가 없어요. 인터넷 연결성이 중요하죠. 앞으로 인터넷 서비스를 하는 기업용 App도 커질 것
이고요.

 트위터 어플을 개발하기 위해선 http를 잘 이해해야 해요. http는 웹서버에 데이터를 전달하기 위한 약속이죠. 그리고 xml은 일반적으로
많이 사용하는 포멧이기 때문에 XML parshing하는 법도 알아야해요.

 웹서비스에 대해 알아보고 갈께요. 웹서비스에 대한 API는 Daum 맵, 구글 맵 등 각 서비스 회사별로 많이 존재해요. 구글 맵은 
사람들이 정말 많이 사용하죠.
 여기서 mashup 이란 API를 이용해서 만들어놓은 web을 이야기 하죠.
 API를 사용할 때 라이센스 조항을 잘 봐야해요. API를 사용할 때 공짜는 없기 때문이죠.

 우리나라에서 웹서비스는 2004년 부터 조금씩 쌓이기 시작했어요. 그래서 web2.0과 상관없이 무딘 발전을 했죠. 외국같은 경우
web2.0발표된 이후로 API를 공개하는 방향으로 했는데 말이죠.
 우리가 webservice를 만들때는 항상 공개 할수 있다고 가정을 하고 만들어야 해요.
 웹서비스가 필요한 이유는요 아직 html분석, 데이터모으기 등을 해서 서비스를 이용하려는 사람들이 있어요. 이런일에 개발자를
투입한다면 개발자 리소스 낭비라고 할 수 있죠. 그런일이 없도록 웹서비스가 필요해요.
 카메라 보여주기 등 증강현실과 관련된 것도 WebService를 이용한 거에요.
 
 웹서비스 중 Twitter API는 가장 쉽고 깔끔한 API중 하나에요. 트위터가 API를 공개해서 성장한 서비스 중 하나죠. 여기선 ListView와
Adapter가 중요해요. Dialog와 Async도 보충적으로 알아야 하죠.

 트위터의 특징을 알아볼께요. 트위터는 나를 보고있는 사람과 내가 보는 사람이 비대칭적이에요. Following과 Follower로 존재하죠.
그리고 미디어적인 성격이 강해요. 내가 하는 것을 다른사람들이 많이 보기 때문에 영향력도 존재하죠.













 트위터 로그인하는걸 연습해봤어요.
 로그인 버튼을 누르면 아이디와 암호를 SharedPreferences에 저장하도록 했죠. 그 후 로그인 액티비티를 종료시키고 메인 List 액티비티를 실행시켰고요.











 트위터 어플을 만들기 위해 API를 분석해 봤어요. 만약 나중에 API를 만들어야 하는 일이 생기면 twitter, Flicker API를 많이 참고해야 해요.
 트위터 API에서 하나하나의 단위를 status라고 해요. status는 우리가 말하는 거의 정보를 담고있죠. 이미지, 날짜, 텍스트, 내용 레이아웃으로 구성되어 있어요.











트위터 API를 사용하여 넘어오는 XML문서를 파싱하기 위해 웹문서를 보았어요. 여기서 http프로토콜을 사용하는데요 http에 대해서 좀 알아볼께요. http는 apache에서 만들었고 java에서 많이 사용해요. 안드로이드에선 http 4.** 때부터 쓰이기 시작했죠. 그리고 REST 라는 걸 알아야 하는데요 REST란 웹의 데이터를 제공하는데 사용되는 구조적인 형식을 말하죠. 구조적으로 저장하는 방식의 예로 URL이 있어요. 이 URL표현에는 많은 정보가 들어가 있어요. 보통 get방식으로 쿼리를 전송하고요 post방식도 쓰는데 이때는 좀 복잡한 form 데이터를 전송하죠. 웬만한 웹사이트는 REST로 구성되어 있어요. 트위터 API는 xml과 REST 를 많이 쓰죠. xml 말고 json도 있는데요 둘중 어떤걸 쓸 지는 상황마다 활용도를 보고 결정하면 되요.
 
 XML parser에 대해 알아볼께요. parser에는 DOM 모델과 스트리밍 모델이 있는데요 DOM은 xml 파일을 다 읽고나서 tree 형태로 메모리에 구성을 하죠. 그리고 스트리밍은 download와 동시에 데이터 처리가 가능해요. 모바일 환경에선 어떻게든 빨리 처리하고 다음으로 넘어가야 하기 때문에 스트리밍 방식을 써야 하죠. DOM으로 하면 메모리를 많이 쓰게 되요. 모바일에선 배터리 절약이 중요하죠. 그런데 초침이 1초에 한번씩 간다면 배터리가 엄청 빨리 달겠죠. 스트리밍도 똑같아요.

  스트리밍 방식에 두가지가 있어요. SAX parser와 pull parser가 있는데요 SAX는 push based방식으로 어떤 태그가 왔다고 계속 알려주는 거에요. pull방식은 내가 태그를 꺼내오는 거에요. 개발자가 지금 태그 가져와!! 택스트 가져와!! 하고 주도권을 갖고 시키는 거죠. 좀더 읽기 쉬운 구조가 되요. 실제 안드로이드 내에서 layout을 분석하는 데 XmlPullParser를 사용하죠. 트위터 API에서 xml 파일을 내려주고 우리는 Pull Parser를 이용해서 API를 분석하는 거에요. XML pull parser를 어떻게 이용하냐면요 첫째, xml을 클래스로 매핑시켜요. 둘째, xml에 대응하는 class 구조를 만들죠. 셋째, 각 class마다 parseXXX 함수를 호출하는 거에요.
 



트위터의 home_time_line을 이용하기 위해 ListView연습을 했어요. home_time_line은 트위터의 main에 보여지는 Line을 이야기 하죠.












신고

'T아카데미' 카테고리의 다른 글

트위터 home_time_line  (0) 2010.07.09
XML Pull Parse  (2) 2010.07.09
트위터 어플개발의 시작  (0) 2010.07.08
쓰레드와 에니메이션  (0) 2010.07.07
데이터 저장 기초  (0) 2010.07.03
메뉴  (0) 2010.07.03
Posted by 응큼미소


쓰레드를 사용한 프로그래스바 예제에요.













에니메이션을 사용한 예제에요












쓰레드 핸들러를 이용한 예제에요.





알람메니져를 이용한 예제에요











신고

'T아카데미' 카테고리의 다른 글

XML Pull Parse  (2) 2010.07.09
트위터 어플개발의 시작  (0) 2010.07.08
쓰레드와 에니메이션  (0) 2010.07.07
데이터 저장 기초  (0) 2010.07.03
메뉴  (0) 2010.07.03
사용자인터페이스_02  (0) 2010.07.02
Posted by 응큼미소

안드로이드에서는 데이터 저장을 어떻게 하는지 알아볼께요

 일단 설정정보 같은걸 저장하는 Preferences에 대한거에요
 원래 content provider의 데이터 모델 예제부터 해보려 그랬는데 전화번호부를 이용한 예제에는 문제가 있어서 넘어갔어요.
 안드로이드에서 전화번호부는 google, 페이스북 exchange등 여러곳에서 sync를 해서 만들어지는데 예전 Api를 사용하면
sync를 한 후에 서로 섞여버리는 문제가 발생할 수 있데요. 

 MediaStore content provider도 있는데 기본적으로 오디오, 동영상, 이미지 타입의 데이터를 지원해요. 근데 얘는 이미지나 음악
을 그때그때 접근하지는 않아요. 뭔가 변화가 있을 때 scanning을 해서 DB에 저장하죠. 그리고 이미지가 큰 것은 sumnail을 미리
만들어서 접근하게 해주고요.





Preferences에 대한 정보는 SDcard에 xml 파일로 저장되요.
 Preferences는 특정 App 안에서만 쓰이는 거에요. 간단한 데이터들(long, String)을 쉽게 저장해주죠. sd card의 각 저장소안에
xml파일로 저장이 되죠. 사용자의 설정값을 주로 저장해요.





EditView에 사용자가 적어놨던 걸 Preferences로 저장한 후 다시 보여주는 예제에요. 저장할 때는 마지막에 꼭 commit을 해야한다는
걸 잊지 마세요.
 세가지 API를 사용하는데요
 getPreferences() 는 한 Activity 안에서만 설정할수 있죠.
 getSharedPreferences() 는 다른 Activity 간에 공유도 가능하게 해요.
 getDefaultSharedPreferences() 는 안드로이드 전체에서 사용하는 공통 설정정보를 가져올수 있게하죠.
 즉, 위에 3가지 호출방식에 따라서 xml의 다른 파일에 저장된다는 뜻이에요.
 Get / Put 메소드를 이용해서 설정에 데이터를 넣거나 빼는게 가능해요.
 그리고 주로 App가 강제로 종료하기전에 설정정보에 저장하고 (onPause()),
다시 시작했을 때 저장된 설정정보를 찾아서 사용해요. (onResume()).







 이번에는 SDcard 또는 내장메모리에 파일을 어떻게 저장하는 지 알아볼께요
 안드로이드에서 파일을 접근할 때는 자바에서의 stream을 그대로 사용해요. input/output stream은 동일하지만 그냥
파일 input output으로 생성하는건 아니죠. 하지만 단말 상의 메인 메모리나 SD카드에서 저장될 때의 저장하는 방식은 서로 달라요.
 안드로이드는 리눅스 기반이기 때문에 내장메모리는 사용자 별로 접근이 가능하죠. 내장메모리에 있는 건 다른 App는 볼수 없다는
말이에요. App마다 사용자 id가 할당이 되기 때문이죠. 그래서 A가 만든 파일은 B가 볼수 없어요. 하지만 SD카드에 저장되면 볼수있죠
 그래서 내장메모리의 openFileOutput() 은 App만 접근할 수 있는 공간을 접근하는 거죠.  
 리소스에 있는 파일은 App에서 수정될수 없고 읽을 수만 있다는걸 기억하세요. 
 SD card에 데이터를 저장하면 공간활용에 좋아서 권한 을 주는데요 SD카드는 보안이 적용안되기 때문에 안전하지 않아요. 그래서
동영상, 이미지등 보안이 중요하지 않은 것들이 주로 저장되죠. FileOutputStream() 은 SD카드에만 적용되는 거에요.
 그리고 파일접근 권한 지정시 EXTERNAL_STORAGE 라고 보통 해주는데 이게 꼭 SD card를 말하는 건 아니에요.
 
 SD카드에 데이터 저장할때 주의할 것 3가지는 manifest 파일에 퍼미션 주는거, 파일 객체 생성할 때 디렉터리 이름을 sdcard로
하는거, 그리고 path 쓸때 폴더 path만 기억해서 써준다는 거에요.









신고

'T아카데미' 카테고리의 다른 글

트위터 어플개발의 시작  (0) 2010.07.08
쓰레드와 에니메이션  (0) 2010.07.07
데이터 저장 기초  (0) 2010.07.03
메뉴  (0) 2010.07.03
사용자인터페이스_02  (0) 2010.07.02
사용자인터페이스_02  (0) 2010.07.01
Posted by 응큼미소

메뉴

T아카데미 2010.07.03 14:39

 이번 시간에는 메뉴에 관한걸 안드로이드에서 어떻게 사용하는지에 대해 알아봤어요.

 메뉴 아이콘으로 쓰는 이미지는 다음과 같죠



메뉴의 UI를 나타내는 xml파일은 다음과 같아요
각각의 버튼을 하나의 아이템으로 해서 icon, title, id만 해주면 되죠.



메뉴버튼을 눌렀을 때의 콜백함수는 다음과 같죠. onCreate()는 딱 한번만 호출되고요 두번째 부터는 onPrepare() 가 불려요.
메뉴에는 옵션메뉴와 context메뉴가 있는데 옵션메뉴는 그냥 단말에서 메뉴버튼을 누르면 보이는 거고요
context 메뉴는 오래 누르고 있으면 나오는 거에요. 숫자에는 제한이 없죠. 다이얼로그로도 나올수 있고 형태는 여러 종류가 있어요.




메뉴를 누를때마다 메뉴의 아이콘을 계속 바꿔주도록 해 볼께요







메뉴의 아이템이 많아지면 더보기 버튼이 생겨요



메뉴의 아이템을 하나 선택했을 때 그 안의 서브메뉴를 보여줄 수도 있죠



뭔가 오래 누르고 있으면 나오는 context 메뉴도 만들어볼께요



context 메뉴의 label 문자도 바꿀수 있고요



context 메뉴안의 아이템이 선택되었을 때 할 동작도 콜백함수로 처리할 수 있어요



이번엔 하드웨어 키보드를 눌렀을 때랑 스마트폰에 제스처를 취했을 때 처리할 일을 구현해 볼께요



스마트폰을 쓰~~윽 Fling 했을 때 글자를 이동시키는 걸 해볼께요





신고

'T아카데미' 카테고리의 다른 글

쓰레드와 에니메이션  (0) 2010.07.07
데이터 저장 기초  (0) 2010.07.03
메뉴  (0) 2010.07.03
사용자인터페이스_02  (0) 2010.07.02
사용자인터페이스_02  (0) 2010.07.01
어플리케이션 구조  (0) 2010.07.01
Posted by 응큼미소

 이번 시간에는 Listview, TabView등 UI를 보이는데 중요한 위젯을 배웠어요. 그럼 List부터 시작할께요. 

 일단 List에 보여줄 객체를 생성해야 해요.







그런데 List의 각 아이템에있는 view에대한 id들을 매번 가져오면 메모리 활용면에 있어서 별로 좋지 않겠죠?
 그래서 view를 재활용하는 방법을 많이 써요. convertView를 이용하는 거죠





TextView를 하나 더 추가한 연습문제에요.
 각각의 아이템을 원하는 layout으로 바꿔줄수도 있는데요 이럴때는 Customized List를 사용해요. getView() 메소드는 새로운 View를
만들기도 하고 단지 데이터만 연결시켜 주기도 하는데요 새로운 View를 이 안에서 만들어서 각자 아이템의 특징을 틀리게 해 줄수가
있죠. 
 이렇게 xml파일은 두개가 필요한데요 하나는 전체 Activity에 사용하는 거고, 하나는 하나의 item에만 적용하는 거죠.
 
 레이아웃 Inflator라는 애도 있는데요 얘는 XML 레이아웃의 내용을 실제 뷰 객체들의 트리로 변환을 하죠. 얘는 Adapter에서
item에 대한 정보를 갖고있는 xml파일을 인스턴스 객체로 만들어서 사용하기 위해 쓰여요.





 각 List의 아이템을 클릭했을 때 할 일을 지정할 수도 있어요
 그냥 한번 클릭했을 때와 오래 클릭했을 때로 나누어 지죠.
 보통 오래클릭했을 때는 설정에 관한걸 많이 보여줘요







 GridView라는 것도 있는데요 이건 표 형식으로 아이템을 보여주죠. 구성은 ListView를 사용하는 것과 동일해요. 하지만 한줄에
여러개가 들어가기 때문에 Colums를 넣어야 하죠. 속성중에 android:numColumns가 있는데 이 속성값을 auto_fit으로 하면
안드로이드는 여유공간이 얼마나 있는지와 나머지 속성들의 값을 참조해서 자동으로 결정해요. spacing 속성을 이요해서는 여백을
줄수 있죠. 여기서는 spinnerview에 맞게 시스템에서 미리 정해놓은 layout을 추천할께요. 바로 simple_spinner_item이에요.
 이렇게 안드로이드 시스템의 내장 레이아웃을 사용할 때도 많은데요 얘네는 보통 android.R 이렇게 시작되죠. 최소한 손가락이 누르기
좋은 크기로 알아서 만들어 줘요. 
 App 내에서 날짜 설정하는 경우도 많기 때문에 날짜/시간 선택기능 위젯도 있죠.
 



comboBox처럼 보여주는 위젯도 있어요. spinner가 그렇죠. list에서 layout을 두가지로 나눠보자고 하면
List에 표시되는 Layout과 다이얼로그에 표시되는 layout이 있어요. 다이얼로그로 표시되는 layout을 spinner라고 하죠.


AutoCompleteTextView라는 것도 있어요. 사용자의 입력을 받으면서 동시에 자동완성을 해 주는 거죠. 이것도 List에서 등용이 되서
쓰이는 거라 Adapter 등으로 처리해 줘요.
 Gallery라는 것도 있는데요 얘는 사진과 같은 것들을 볼수 있는 간편한 기능을 제공하는데요, View들이 수평으로 쭈욱 이동되는 거죠.
이것도 일종의 Adapter View라고 볼 수 있어요.

나중에 twitter와 관련된 프로젝트를 하기위해 twitter가입도 했어요



TabView를 볼께요.
 뷰의 탭부분을 설정하는 데에는 3가지가 필요한데요 TabHost는 모두 아우르는 것으로 메인 컨테이너라고 할 수 있죠.
 TabWidget은 탭 버튼을 담고있는 한 아이템을 구현현 것으로 아이콘과 텍스트로 구성되요. 그리고 FrameLayout에 탭 내용이
담기게 되죠. 
 여기서 주의할게 있는데요 TabHost는 평소 하던데로 +id만 하면 되지만 이건 App만 아는거기 때문에 시스템은 잘 몰라요.
 그래서 만약 TabWidget과 FrameLayout까지 이런식으로 해버리면 시스템이 알아서 접근을 할수가 없죠.
 그래서 시스템이 여기에는 알아서 접근할 수 있도록 개발자와의 약속을 해놓은 @android:id/tabs 와 @android:id/tabcontent 를
이용해야 해요.
 일반적으로 텝위젯을 사용할 때는 Activity를 먼저 구현한 후에 TabActivity에 추가해 주는 순서로 해요.

 손잡이 잡아당기는 위젯은 SlidingDrawer Widget이라고 하죠.









웹킷을 이용해 웹사이트를 보여주는 WebView를 볼께요.
 안드로이드에선 Activity에서 바로 html 내용을 보여줄 수 있어요. 완벽하게 지원을 해주죠. 그리고 웹킷엔진을 사용해요.
 웹킷 엔진은 웹브라우저, 웹뷰 웬만한건 다 되죠. 주의할 점은 인터넷 연결권한(INTERNET)이 있어야 한다는 거죠. 연결방식은 어떤 연결방식을 사용하더라도 상관없어요. WiFi, 무선통신망, Bluetooth 뭐든지 말이죠.








 사용자에게 URL주소를 입력받아서 이용할 수도 있어요



진짜 웹브라우저랑 비슷하게 만들기 위해 웹브라우저의 공개된 소스를 보도록 할께요
 기본 App에 있는걸 내가 처리하고 싶으면 이렇게 오픈소스를 다운받아서 하면되요.
 근데 여기서 문제점이 하나 발견되죠. onCreate() 메소드에 startActivity(ACTION_VIEW, "http://~~~") 이거를 해놓으면 웹에서
link를 클릭할 때마다 stack에 화면이 계속 쌓이게 되요. link된 화면으로 넘어가지 않죠. 그래서 Activity 하나가 startActivity 를 모두
처리하게 해야 하는데요 onNewIntent() 를 이용하면 되요. getIntent에서는 처음 StartActivity 만 처리하고 두번째 부터는
onNewIntent() 가 호출되기 때문이죠. 그런데 이 특징이 적용되게 할라면 manifest 파일에서 런치모드를 singleTask 로 해야해요.
 이렇게 되면 처음에 Activity는 버튼으로 웹킷을 사용하지만 그 다음 두,세번째 부터는 넘어온 URi로 웹킷을 사용하는 거죠.









intent filter부분을 참고해서 이용하면 되겠죠?



그렇게 되면 intent-filter가 두개기 때문에 어떤 application으로 처리할지 선택하는 다이얼로그가 나오죠



우리가 만든 인텐트를 받도록 설정해 볼께요





그런데 한번 웹킷을 사용했다가 다시 접속하려고 하면 페이지를 넘어가지 않아요. 새로운 인텐트를 처리하도록 하지 않았기 때문인데요, onCreate에서 가져온 인텐트로는 새로운걸 처리할 수 없죠. 그래서 onNewIntent라는 콜백메소드를 만들어야 해요.









신고

'T아카데미' 카테고리의 다른 글

데이터 저장 기초  (0) 2010.07.03
메뉴  (0) 2010.07.03
사용자인터페이스_02  (0) 2010.07.02
사용자인터페이스_02  (0) 2010.07.01
어플리케이션 구조  (0) 2010.07.01
사용자인터페이스_01  (0) 2010.07.01
Posted by 응큼미소
 이번시간에는 애플리케이션의 구성요소인 서비스와 브로드케스트리시버를 공부했어요. 하지만 서비스는 이미지를 남길수가 없었죠. 그래도 필기해놓은게 있으니 곧 설명을 남길께요.

서비스라는 애는 UI가 없이 뭔가 background에서 조용히 일처리를 하고 사라져요. 이런 서비스를 통해서 IPC를 구현할 수도
있는데요 서로다른 Process 사이를 연동시키는 거죠. binder라는 서비스가 이런걸 해 줘요.
 그냥 startService() 만 하면요 별도의 쓰레드는 만들지 않아요. 하지만 CPU를 많이 쓰거나 대기 상태를 요구하는 서비스는
별도의 쓰레드를 만들 필요가 있죠. 그럴때는 bindService() 를 호출해요. IPC를 담당하는 서비스는 보통 이렇게 하죠. 이 쓰레드
를 잘 사용해야 사용자들이 체감속도를 좋게 느낄 수 있어요.
 Service도 LifeCycle 이 있어요. 하지만 Activity와는 좀 틀리죠. 화면에 보이는게 없으니깐 당연히 그렇겠죠. 그래서 resume,
pause, start, stop 이 필요없어요. 그리고 startService는 여러번 호출해도 서비스는 하나만 생겨요. 서비스는 Activity같이 
stack에 쌓이고 이런게 아니라 백그라운드에 하나만 생기는 거기 때문에 그렇죠. 서비스는 stopself()를 통해 Destroy 시킬 수 
있어요.

 나중에 보게 되겠지만 content provider가 있는데요, 얘는 내부적으로 갖고있는 데이터를 다뤄요. A가 만든 데이터를 B가 접근
하는 건 불가능 한데요 그래도 공유하고 싶을 때가 있죠. 전화번호부나 사진 같은거요. 이 때 content provider를 사용해서 SQLite
를 이용해요. 이런걸 SendBox Model 이라고도 하죠.

그럼 브로드케스트리시버부터 볼께요. 얘를 통해서 메일도착, 날짜, 위치이동 등의 정보를 App에게 알려줄 수 있어요.
브로드캐스트리시버는 다른 App도 관심이 있을 만한 이벤트를 뿌려주죠. 그리고 registerReceiver메소드를 이용하면
런타임시 실행코드 상에서 관심이 있다고 등록할 수 있어요.
 브로드캐스트리시버는 onReceive() 콜백 함수만 구현하면 되는데요 받았다는 것만 표시하고 바로 내려가는 간단한 작업을
하게 되죠. 그래서 오래걸리는 작업이라면 Service에게 맡기는게 좋아요.
 지금 메모리에 떠있는 App에게만 주는 이벤트도 있는데요 예를 들어 1분마다 바뀐 시간을 알려주는 이벤트에요.
모든 App에게 1분마다 이벤트를 보내주면 시스템에 엄청 과부하가 걸리겠죠. 그런 애들을 꼭 registerReceiver를 이용해서
메모리에 떠있는 애만 받도록 등록해야 해요.
 App는 어떤 브로드캐스트에 관심이 있다고 intent-filter에 등록을 해야하죠. 그래서 만약 SMS가 왔을 때 알려줄 수 있는
App가 올라와있지 않다면 시스템이 알아서 App올려주고 브로드캐스트를 부르게 되죠. 

 여러 브로드캐스트가 왔을 때 순차적으로 실행하도록 할 수도 있어요. sendOrderedBroadcase()메소드를 이용하면 가능하죠.
 이런게 왜 필요하냐면요 스팸차단을 하고싶다고 해보죠. 근데 스팸차단은 sms 브로드캐스트와 전화가 오는 브로드캐스트 등을
보고 스팸차단을 해서 그런 브로드캐스트를 막아야겠죠? 이런 경우에 순차 브로드캐스트가 필요하죠. 그리고 어떤 패키지가 추가가 
되었는데 위험하다 등등을 알려주는 브로드캐스트 같은 경우도 우선순위가 높아야 겠죠?
 부팅이 되자마자 실행해야 할 브로드캐스트가 있을수도 있는데요 이럴때는 manifest 파일에 사용자의 permission 주는게 필요해요.
BOOT_COMPLETED라는 permission이 필요하죠.
 
 여기서 실수하기 쉬운게 있는데요 UI가 없는 Service나 broadcast는 Run Configuration에서 설정할 수 없죠.

여러 브로드케스트 예제를 쭈욱 보겠습니다.











content provider라는 애는 다른 App나 컴포넌트들이 데이터를 쉽게 공유할 수 있도록 해 주죠. 
Application이 직접 원격 저장소에 접근할 수 없기 때문에 content provider를 이용해서 간접적으로 접근하게 되죠.
접근할 데이터 셋을 지정할 때는 URI를 사용하는데요 "content://" 이렇게 시작하는 거죠. 어떤 컴포넌트던지 자신만의 URI
가 정해져 있어요. 이 URI를 이용해서 다양한 Activity를 띄우는게 가능하죠.  
SQLite 데이터베이스가 많이 쓰여요.


이제 ListView에 대해 알아보겠어요
 ListView는 고급 View중에서 가장 많이 사용되는 view에요. ListView에 대해서 알아보기 앞서
 고급 위젯에서 두루두루 쓰이는 구조가 바로 ListView, Adapter, Data인건 기억해야 해요.
 ListView는 똑같은 모양의 item들이 여러개 반복될 때 사용되요. 구지 Linear Layout을 써도 되는데 이걸 왜 쓰냐면요
Linear layout을 쓰면 메모리를 많이 쓰게 되거든요. 아이템이 몇만개가 있다고 생각해 보세요.
하지만 ListView는 몇 만개 까지도 처리할 수 있어요. 메모리가 재활용 되기 때문이죠. 맨위의 TextView가 없어지면
밑에 올라오는 TextView를 재활용해서 보여주죠. 어뎁터가 ListView와 backend를 연결해 줘요.
 ListView는 하나이고 각각의 TextView (itemView)는 여러개 인데요 이 아이템들을 재활용해서 보여주는 거에요.




시스템폰트들이 있는 곳입니다.



리스트와 item을 연결해주는 Adapter를 직접만들수도 있어요
근데 왜 v.findViewById()를 할까요? 그건 리스트 안에선 아이디가 동일하지만 아이템 안에선 아이디가 유일하기 때문이에요.
그래서 아이템에 대한걸 결정해 줄때는 매번 아이템의 View v 를 이용해야 하죠.
 adapter에는 CursorAdapter라는 애도 있는데요 얘는 content provider에서 받을 수 있는 데이터를 선택가능한 뷰에 보여주기 위해서
쓰여요. 
 Adapter가 왜 필요하냐면요
 ListVeiw가 특정한 모양을 갖고 있는건 아니에요. 물론 Layout보다 훨씬 복잡한 일을 하긴 하지만 일단은 item을 배치시켜주는 역할
만 하죠. 바로 Adapter가 item을 만들어서 ListView에 공급을 해줘요. 화면에 표시될 수 있도록 Adapter가 바꿔서 전달을 하죠.
 그래서 Adapter의 Layout은 하나하나의 item에 들어가는 레이아웃이라고 볼 수 있어요.
 복잡한 형태의 List를 만들때는 ArrayAdapter를 상속받아서 필요한 부분만 구현하면 되죠.
 Adapter에서 제일 중요한 함수는 getView인데요 ListView가 하나하나의 아이템을 그릴 때마다 Adapter에게 어떻게 그리는지 
물어보는데 Adapter는 이 함수를 통해서 대답을 한다고 보면 되죠. 이 함수의 파라미터 안엔 포지션도 있기 때문에 어느 위치의
아이템을 그리는 지도 볼수 있어요.파라미터 중 convertView도 있는데 이건 재활용할수 있는 View를 나타내죠.
 ListView에 있는걸 선택하고 고르는 View 역시 Adapter를 통해서 연동이 되는데요 방대한 데이터로 하기에는 좀 무리가 있죠.
 Adapter의 item으로 들어가는 속성중에서 minHeight라는 게 있는데요 이건 item의 최소높이가 아무리 작아도 이정도는 되게 하라는
거에요.



 시스템과 App간에 약속된 id값도 있는데요 이렇게 미리 정의된 id를 사용해야 할 경우에는 @android:id 를 사용하면 되요.
 



포지션을 호출해 여러가지 응용을 할 수 있어요





신고

'T아카데미' 카테고리의 다른 글

메뉴  (0) 2010.07.03
사용자인터페이스_02  (0) 2010.07.02
사용자인터페이스_02  (0) 2010.07.01
어플리케이션 구조  (0) 2010.07.01
사용자인터페이스_01  (0) 2010.07.01
안드로이드 개발환경  (0) 2010.06.27
Posted by 응큼미소
 오늘은
 안드로이드의 내부-인텐트, 애플리케이션 구성요소, 액티비티 수명주기등을 알아보도록 할께요.

아 그전에 아직 테이블 레이아웃을 보지 않았으니깐 잠깐 알아보고 갈께요. 스크롤뷰도요





만약 어플리케이션이 죽는다면, DDMS의 logcat을 분석해서 디버그를 할 수 있어요.



xml파일에 있는 리소스를 가져오도록 해 볼께요







안드로이드 개발에 있어서 가장 주용한 개념인 intent라는 게 있어요. 뭔가 하려고 하는 일, 즉 어떤 작업을 할건지 담아놓은 객체죠
인텐트의 구성요소로 액션, 데이터, 카테고리가 있는데요, 액션은 어떤동작을 할지 정하는 것으로 ACTION_VIEW는 보겠다,
ACTION_EDIT는 편집을 하겠다는 걸 뜻해요.
 데이터는 하려는 일을 하는 데이터를 나타낸건데 Uri로 표현이 되요. Uri는 URL같이 표시되죠. 그런데 URL과 다른점은 
URL은 우리가 읽기 쉽게 표현되 있는거고, Uri는 시스템이 읽기 쉽게 표현되 있는거에요. 그래서 Uri.parse() 함수를 사용해
우리가 읽기 쉬운 URL을 시스템이 읽기 쉬운 Uri로 바꿔주죠.
 Uri를 지정할 때 content: 이렇게 쓰는데요 이렇게 적어줌으로써 시스템이 액션과 데이터를 조합하여 Activity를 보여주게 되죠. 
  액션과 데이터를 적어주지 않고 컴포넌트 이름을 적어줄 수도 있는데요, Activity를 직접지정하는 거죠. 시스템은 pakage이름을 보고
특정 App를 찾아간후, Class이름으로 특정 class를 찾아가요. 이걸 바로 명시적 인텐트라고 하고, 액션이나 데이터를 사용하는 걸 
암시적 인텐트 라고 해요.
 category는 특정 컴포넌트에 대한 부가적인 정보를 여기 넣어준다고 생각하면 될 거 같애요.
 이런 인텐트는 다른 App간에 서로의 App를 띄우는 모든 경우에 사용되고요, 컴포넌트와 컴포넌트 간 데이터를 전달할때 전부
인텐트가 들어가죠. 
 하나의 App는 하나의 VM에서 돌아가요. 그리고 리소스를 공유하죠. 

Activity에 대한 category를 넣어줄 수 있습니다. 추가적인 정보를 말하죠. 예를 들어 category의 이름이 CATEGORY_LAUNCHAR면
시스템은 이 인텐트필터를 포함하는 액티비티를 홈 스크린에 보여줘요.



Activity가 어떤 동작에 관심이 있는지 설정하기 위해 intent-filter를 만들수 있어요. 인텐트 필터는 시스템에 있는 Activity Manager에게
이 Activity는 어떤 인텐트에 대해 관심이 있고, 그 인텐트가 들어오면 어떤 동작을 할 지 알려주죠. 예를들어 이 안에 '나는 VIEW 액션과 http 데이터가 들어오는 인텐트를 받아들일 수 있는 Activity다!! ' 하고 명시해 줄 수 있어요.



처음 시작될 Activity를 바꿀수도 있어요
여기서 알고가야 할게 있는데요, 하나의 사용자 시나리오를 처리하는 데 하나의 App로만 구성된 건 아니라는 거죠. 예를들어 
그림편집을 하고 메일로 보내는 시나리오가 있다면 그림편집 App에서 '그림선택 App'를 사용하고, 메일 보낼때는 'gmail App'
를 사용해요. 이렇게 사용되는 Activity의 묶음을 task라고 하죠. 각각의 App는 각각의 process를 갖고 있어요. 새로운 App가 
나타날 때마다 Activity stack에 쌓이게 되죠.
 인텐트의 중심에는 Activity Manager가 있어요. 얘가 한쪽 App에서 intent를 받고 다른 App를 실행시켜 주죠. 인텐트를 만들면
시스템에 등록을 해 줘요. 그럼 시스템이 수집을 해서 실제 intent 요청이 왔을 때 적당한 Activity에 매칭을 시켜줘요.
 이게 바로 안드로이드에서 멀티태스킹의 핵심이에요. 여러개의 task랑 프로세스가 잘 돌아가게 만들어 놓았죠. 



인텐트를 사용하는 모습들이에요. 인텐트를 띄운 결과를 알고싶을 때 startActivityForResult 함수를 사용하죠.











그런데 인텐트를 사용해 전화를 걸려고 하면 어플리케이션이 종료되버려요. 퍼미션이 없기 때문이죠. 그래서 퍼미션을 설정할 수도 있습니다. 퍼미션으로 App가 접근할 수 있는 영역을 정할 수 있어요.





Activity간에 데이터를 전달할수도 있어요
Activity가 무엇일까요? 액티비티는 보통 하나의 화면을 표현하죠. 그려주기도 하고, 입력도 받고 해요. 액티비티를 사용하므로써
컴포넌트 재사용을 할 수 있죠. 이전에 실행된 액티비티는 차곡차곡 스택에 쌓이기 때문에 스택에 있는게 pop되면서 재사용
할 수 있어요. 이렇게 액티비티가 여러개 쌓여서 실행되는 걸 task라고 하죠. 여러 App가 상호연동하면서 동작하게 되요. 
 Activity간 데이터를 전달할 때는요 A란 Activity는 putExtra() 로 데이터를 집어넣어서 B에게 전달하고, B는 getExtra()로 데이터를 
가져오죠. B는 Activity 상태값을 돌려줄 수도 있어요.

 인텐트는 데이터 전달을 위해서만 쓰일수도 있어요. 결과값이 올 때 Callback 메소드가 호출이 되죠. 결과값을 받기를 원하면 
startActivityForResult(~~, code) 함수를 이용해서 인텐트를 전달하면 되요. 여기서 code를 왜 주냐면요 인텐트를 전달하는 
A라는 Activity는요 액티비티 B 뿐만 아니라 다른 액티비티인 C를 호출할 수도 있기 때문이에요. 그래서 서로 구분해 주기 위해 
code를 쓰죠.









manifest파일의 역할에 대해서 조금 알아보고 넘어갈께요.
App의 자바 패키지 이름을 지정해요. 패키지는 시스템 상에서 유일하게 구분되는 이름이죠.
App의 컴포넌트에 대해서도 시스템에게 설명해줘요. 컴포넌트에는 액티비티, 서비스, 브로드캐스트 리시버, content provider
가 있죠.
App가 가져야 하는 권한에 대해서도 나와있어요. 다른 App가 접근할 때의 권한에 대해서도 나와있죠.
안드로이드 버전이 워낙 여러개라서 API의 최소레벨도 나와있어요.
그리고 App에 필요한 라이브러리 리스트도 나와있죠.
원래는 하나의 App가 하나의 Process에 매핑이 되는데 가끔 사용하는 프로세스를 변경해서 써야 할 경우도 생기게 되요.
그럴때는 '이 서비스는 따로 20M의 process를 써라' 라는 정보도 넣어줄 수가 있죠.
manifest파일에 있는 intent-filter 엘리먼트는요 이 컴포넌트가 어떠한 상황에서 호출이 될 껀지 결정해줘요.

 어플리케이션엔 수명주기라는 게 있는데요 시스템이 스스로 관리하는거죠. 시스템은 사용자가 process에 대해 신경슬 필요없도록
알아서 판단해서 process를 관리해요. 안드로이드에 종료버튼이 없는 이유이기도 하죠. 시스템은 메모리를 확보하기 위해서
App process를 죽이는데요 그냥 죽이는 건 아니고 중요하지 않은 순서로 제거해요. 포커스가 있는 애는 제일중요한 애고
포커스는 없지만 보이고 있는 애는 그 다음으로 중요한 애고, background로 stack에 존재하는 애는 덜 중요한 애이죠. 그리고
특정 컴포넌트가 실행할 때 알아서 프로세스를 올려줘요. 프로세스는 그래도 죽을때 죽는다고 얘기는 하고 죽죠.
 새로운 Activity가 시작되면 스택의 맨 위쪽에 넣어지고 그 전에 있던 애들은 하나하나씩 없어지면서 밑으로 가요. 얘네는
언제든지 메모리에서 사라질수 있는 애들이죠. 주의할 점은 프로세스가 사라진다고 stack에서 사라지는 건 아니라는 거에요.
 
 액티비티는 수명주기를 가져요. Running, Paused, Stopped, Destroyed 이렇게 4개가 있는데요
Running은 포커스를 가진상태이고
Paused는 포커스를 잃은 상태이고 화면에는 보이는 중이죠.
Stopped은 화면에도 보이지 않고 stack에 쌓여있는 상태에요.
Destroyed는 메모리에도 남아있지 않고 사라지는 거죠.

 액티비티는 처음에 생기면 OnCreate() 가 호출되요.
그리고 OnStart() 에 의해 화면에 보이게 되죠.
OnResume() 으로 포커스를 가지게 되요.
여기까지 하면 Running상태가 되죠.
Running에서 onPause() 가 호출되면 Paused 상태가 되면서 포커스를 잃게되요.
하지만 다시 onResume() 로 포커스를 얻을 수 있죠.
Paused 상태에서 onStop() 이 호출되면 화면에도 보이지 않고 스택에 쌓여 있기만한 Stopped 상태가 되죠.
여기서 다시 Running으로 가서 포커스를 잡으려면
onRestart() 를 호출하고 --> onStart() 로 화면에 보인 후 --> onResume() 으로 포커스를 잡아야 해요.
 이렇게 액티비티가 화면에 보여지는 생애기간은 onStart() 메소드를 호출할 때부터 onStop() 메소드를 호출할 때까지
라고 할 수 있죠.

 그럼 onCreate() 부터 볼께요
여기서는 setContentView() 를 이용해서 화면구성을 해요. 그 다음에 Intent에서 받아온걸 처리하죠. 
 onPause() 는 포커스를 다른 Activity에게 넘기는 거에요. 내께 다 끝나서 stack의 top이 실행되어 새로운게 덮어씌여지는거죠.
 얘는 주로 데이터를 저장소에 저장하거나 할때 많이 쓰여요. 그리고 이 상태의 Activity는 시스템이 강제로 종료시킬수도 있는데요
그래서 Date를 저장소에 저장해야 하는거에요.
 onPause() 와 onResum() 은 새로운 Activity가 올라오거나 사라지는 거기 때문에 사용자가 부드럽게 느끼려면 시간을 짧게 해야
해요. 
 onDestroy() 는 액티비티가 없어지기 전에 호출이 되요. 더이상 Activity가 쓸모가 없어진 거죠. back키를 눌렀을 때 호출이 되죠.
 즉, onPause(), onStop(), onDestroy() 메소드가 강제종료될 수 있는 애들인데요 onPause() 만이 강제종료되기 전에 확실히
호출되는 메소드이고 onStop(), onDestroy() 메소드는 호출되지 않을수도 있기 때문에 데이터 저장등의 코드는 꼭 onPause()
에 있어야 해요.
 새로운 액티비티가 덮어 씌어지는거랑 다이얼로그랑은 전혀 틀려요. 다이얼로그가 떴을 때 상태변화는 전혀 없죠.
 반투명 윈도우로 액티비티를 보여줄 수도 있는데요 이렇게 되면 새로운 Activity가 올라오긴 하는데 반투명상태라서 예전 Activity도
보이긴 하죠. 근데 입력을 할순 없고요. 
 back key와 home key를 눌렀을 때 차이가 좀 있어요.
 back key를 눌렀을 때는 Activity를 종료시키는 거고요 home key를 눌렀을 때는 사용할 여지를 남겨놓는거죠. 그래서 스택에도
Activity가 쌓인 채로 있는데요, 만약 A 에서 B 를 호출하고 home key를 누른 후 다시 들어오면 A부터 실행되는게 아니라 B가
실행이 되는거죠.
 그리고 phone에서 stop버튼 누르면 대기상태로 갔다가(paused) 다시 menu버튼을 누르면 resume이 되요.
 지금까지 본것처럼 Activity를 보여줄 때는 stack에 올라가는가? 화면에 보여져야 하는가? 포커스를 가져야 하는가? 등을 신경
쓰는게 중요해요.
 안드로이드에서의 바탕화면은 window의 바탕화면과 틀려요. 내가 하던 App위에 바탕화면 App를 덮어 씌었을 뿐이죠.
 

Activity 데이터 교환을 이용한 예제예요






 시스템에 메모리가 없어서 프로세스를 갑자기 죽일 때는요 그냥 죽이는건 아니고 saveInstanceState() 와 restoreInstanceState()가
호출이 되요. saveInstanceState()는 현재 상태를 저장해야 하는 시점에 불리게 되죠. restoreInstanceState()는 파일에 저장되있던 값
을 되돌려 놓으라는 거에요. 이게 호출될 때는 Activity가 스택에 있다해도 다시 불릴때 create부타 다시하죠.

 아래는 두 Activity를 이용해 수명주기를 확인하는 예제에요



 
신고

'T아카데미' 카테고리의 다른 글

사용자인터페이스_02  (0) 2010.07.02
사용자인터페이스_02  (0) 2010.07.01
어플리케이션 구조  (0) 2010.07.01
사용자인터페이스_01  (0) 2010.07.01
안드로이드 개발환경  (0) 2010.06.27
안드로이드 개요  (0) 2010.06.26
Posted by 응큼미소


티스토리 툴바