현재 자바모델링(http://javamodeling.com)에서 스터디에 참가하고 있다.

Struts2를 학습하던 중에 이 글의 제목과 관련된 내용을 만나볼 수가 있다.
위와 같은 문제가 발생을 하는 경우를 접하게 되었다. 가만히 읽어보면, result success 가 정의되지 않았다는 이야기를 내보내고 있다.

이 증상과 관련된 소스는 struts2.xml 과 LoginAction_KJH.java 와 관련이 되어 있다.
정확하게는 스트럿츠에서 사용하는 interface com.opensymphony.xwork2.Action 에 정의된 SUCCESS와 관련이 되어 있다.


struts2.xml
       
<action name="login" class="com.javamodeling.struts2.login.LoginAction_KJH">
       <result name="success">success.jsp</result><!-- return SUCCESS 인데, 찾는건 소문자로 찾네? -->
       <result name="error">failure.jsp</result>
</action>

LoginAction_KJH.java
        public String execute() {
           
            if (this.userid.equals(this.password)) {
                return SUCCESS;
            } else {
                return ERROR;
            }
        }

interface com.opensymphony.xwork2.Action 에서 정의한 SUCCESS를 확인해보자.
항목에서 SUCCESS = "success"로 선언되어있는 것이핵심이다. ^^;

LoginAction_KJH.java 소스에서는 return SUCCESS 를 보면 "SUCCESS"가 리턴될 것 같은 것이 일반 사람들의 마음이다(나만 그럴까?)

strtus.xml 을 보면 <action></action> 태그 사이에 <result name="success">success.jsp<result/>로 적어놓은 것이 보일 것이다. 물론 이렇게 되어 있으면 정상적으로 작동한다. 혹시, <result name="SUCCESS">success.jsp<result/>로 작성되어 있지 않은지 확인해보자.

"SUCCESS"로 되어 있다면 "success"로 수정을 하자. 그런 후에 실행해보자.
정상적으로 실행이 되는 것을 확인해볼 수 있을 것이다.

이런 원인은 JUnit TestCode를 작성하여 확인해볼 수 있었다. excute()에서 리턴되는 값 때문에 생긴문제라는 확신을 하게 되었다.
요즘 TDD(Test Driven Development)에 대해서 공부를 하고 있는데, 이렇게 활용할 수 있다는 발견에 공부한 보람을 느끼며 더 열심히 해야겠다.

"SUCCESS"를 "success"로 변경하면,
정상적으로 실행된 것을 확인해볼 수 있다. 이를 통해서, LoginAction_KJH.java의 execute()에서 return SUCCESSreturn ERROR의 반환값을 확인해볼 수 있다.

이런 인식의 오해를 해결하는 방법이라면

return "SUCCESS" 나 return "success"와 같이 반환되는 값을 정확하게 정의를 해주고 나서
struts.xml 에서 <result name=""></result>에서 name을 정의해주는 것이 아닐까?

 

  • tools.xml 추가

    tools.xml.jpg

  1. <tools>
        <data type="boolean" key="xhtml" value="true"/>
        <data type="boolean" key="isSimple" value="true"/>
        <data type="number" key="version" value="2.0"/>
        <toolbox scope="request">
            <tool key="toytool" class="ToyTool" restrictTo="index*"/>
        </toolbox>
        <toolbox scope="session">
            <tool key="map" class="java.util.HashMap"/>
        </toolbox>
    </tools>

 

  • web.xml 아래 항목 추가

    web.xml.jpg

  1.    </servlet-mapping>
        <servlet>
        <servlet-name>velocity</servlet-name>
        <servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class>
        <!-- servlet-class 위치가 1.6 버전에서는 보는 것처럼 ...view.servlet... 으로 바뀜 -->
      </servlet>
      <servlet-mapping>
        <servlet-name>velocity</servlet-name>
        <url-pattern>*.vm</url-pattern>
      </servlet-mapping>
      <welcome-file-list>
        <welcome-file>index.vm</welcome-file>
      </welcome-file-list>

 

  •   index.vm

  1. <html>
    <body>
    I'm a velocity template.

    #if( $XHTML )
      #set( $br = "<br />" )
    #else
      #set( $br = "<br>" )
    #end

    $br
    $br

    Here we use a custom tool: $toytool.message

    $br
    $br

    Here we get the date from the DateTool:  $date.medium
    </body>
    </html>

index.vm.jpg

 

 

이 글은 스프링노트에서 작성되었습니다.

'Programming' 카테고리의 다른 글

What dows 'PMD' mean?  (0) 2010.12.31
[Velocity] velocity.properties  (0) 2010.03.13
100207_발표내용정리  (0) 2010.02.07
나도 Java Champion 될 수 있을까?  (0) 2010.01.09
[펌] 2010년 전략 기술 톱 10  (0) 2009.10.26
방법은 간단하다.
java -jar 파일명.jar
하면 된다.

이클립스를 사용하다가 중간중간 PerGem space와 관련된 창이 뜨면서 오동작을 일으켰다. 그래서 찾아봤다.
http://www.soulforged.net/wordpress/2007/06/12/out-of-pergem-space/
-XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=128m -Xmx512M
위 옵션을 eclipse.exe 실행 항목에 뒤에 추가해주면 된다.

목차


  1. 목차
  2. 인턴트 소개
    1. 인텐트를 이용해 액티비티 띄우기
      1. 명시적으로 새 액티비티 시작시키기
      2. 암시적 인텐트와 늦은 런타임 바인딩
      3. Linkify 소개
        1. 네이티브 링크타입
        2. 커스텀 링크 문자열 만들기
        3. 매치 필터 사용하기
        4. 변형 필터 사용하기
      4. 액티비티 결과

        1. 서브 액티비티 띄우기
        2. 결과 리턴하기
        3. 서브 액티비티 결과 다루기
        4. 네이티브 안드로이드 액션
    2. 인텐트 필터를 이용해 암시적 인텐트 서비스하기
      1. 안드로이드가 인텐트 필터를 해결하는 방법
      2. 인텐트 필터 매치에 반응하기
      3. 책임 떠넘기기
      4. 연락처 선택 예제
    3. 플러그인과 확장성을 위한 인텐트 필터 사용

      1. 애플리케이션에 익명 액션 제공하기
      2. 액티비티 메뉴에 익명 액션 통합하기
    4. 이벤트 방송을 위한 인텐트 사용
      1. 인텐트로 이벤트 방송하기
      2. 브로드캐스트 수신자로 방송에 귀 기울이기
        1. 애플리케이션 매니페스트에 브로드 캐스트 수신자 등록하기
        2. 코드로 브로드캐스트 수신자 등록하기
      3. 네이티브 안드로이드 브로드캐스트 액션
  3. 어댑터 소개
    1. 어댑터를 이용한 데이터 바인딩
      1. 할 일 목록 ArrayAdapter 커스터 마이징
      2. SimpleCursorAdapter 사용하기
  4. 인터넷 리소스 소개
    1. 인터넷 리소스에 접속하기
    2. 인터넷 리소스 이용 극대화
  5. 다이얼로그 소개
    1. Dialog 클래스 소개
      1. AlterDialog 클래스
      2. 전문 입력 다이얼로그
      3. 다이얼로그 사용과 관리
    2. 액티비티를 다이얼로그로 사용하기
  6. 지진 뷰어 만들기
  7. 요약
  8. 보충 - 안드로이드 관련 근황

 

Chapter 05. 인텐트, 브로드캐스트 수신자, 어댑터, 그리고 인터넷

 

작성자 : 김지헌

 

목차#

  • 인턴트 소개
  • 어댑터 소개
  • 인터넷 리소스 소개
  • 다이얼로그 소개
  • 지진 뷰어 만들기
  • 요약

100207_AndroidMindMap_Intent.png

인텐트 소개#

인텐트(intent)는 어떤 액션이 수행되어야 한다는 사용자의 의향을 선언할 수 있도록 해주는 메시지 전달 메커니즘으로 사용된다. 이때 액션은 데이터의 특정 부분을 가지고(혹은 데이터의 특정 부분에 대해) 수행되는 것이 보통이다.

인텐트를 사용해, 어떤 애플리케이션에 속한 것이든 관게 없이 안드로이드 장치에서 사용 가능한 모든 애플리케이션 컴포넌트 간의 상호작용을 지원할 수 있다. 이는 독립적인 컴포넌트들의 컬렉션을 서로 연결된 단일 시스템으로 바꿔준다.

인텐트의 가장 흔한 용도 가운데 하나는 새 액티비티를 명시적으로(읽어 들일 클래스를 지정함으로써)나 암시적으로(데이터의 어느 한 부분에 대해 수행되는 액션을 요청함으로써) 시작시키는 것이다.

인텐트는 또한 시스템 전역에 메시지를 방송하는 데에도 사용될 수 있다. 어떤 애플리케이션이든 브로드캐스트 수신자를 등록해 이들 브로드캐스트 인텐트에 귀 기울이고 반응할 수 있다. -> 이벤트 중심 애플리케이션을 만들 수 있다.

 

인텐트를 이용해 액티비티 띄우기#

애플리케이션에서 다른 애플리케이션 화면(액티비티)를 오픈하려면, 다음의 코드에서 보는 바와 같이 startActivity에 인텐트 하나를 전달해 호출한다.

  1. startActivity(myIntent);

이 Intent는 오픈할 클래스를 명시적으로 지정하거나, 수행되어야 하는 대상인 액션을 포함할 수 있다. 후자의 경우, 런타임은 "인텐트 확인"이라는 과정을 통해 오픈할 액티비티를 고를 것이다.

명시적으로 새 액티비티 시작시키기#

※ 여러 화면(액티비티)는 반드시 애플리케이션 매니페스트 안에 포함되어야 한다.

시작시킬 액티비티 클래스를 명시적으로 선택하려면, 현재 애플리케이션 컨텍스트와 시작시킬 액티비티 클래스를 지정하는 새로운 인텐트 하나를 만든다.

  1. Intent intent = new Intent(MyActivity.this, MyOtherActivity.class);

  2. startActivity(intent);

startActivit를 호출하고 나면 새로운 액티비티가 생성되어화면에 보여지고, 활성화 상태가 되며, 액티비티 스택 맨 위로 이동된다.

이 새로운 액티비티에 finish를 호출하면 액티비티가 종료되어 스택에서 제외될 것이다. 아니면 그렇게 하지 않고 장치의 뒤로 가기 버튼을 사용해 이전 액티비티로 이동할 수 있다.

암시적 인텐트와 늦은 런타임 바인딩#

암시적 인텐트(Implicit Intent)는 익명의 애플리케이션 컴포넌트가 액션 요청을 서비스를 할 수 있도록 하는 매커니즘이다.

Intents.png

암시적...이란 무엇일까? ㅡ_-)? ->> 개발자가 사용하는 기능을 가지고 있는 애플리케이션이 어떤 것인지 정확히 알지 못해도 된다는 것.

액티비티를 시작시키기 위해 이 새로운 암시적 인텐트를 사용하면, 안드로이드는 지정된 데이터 타입에 대한 액션 수행에 가장 적합한 클래스로 그 인텐트를 해결한다.

    if( somethingWeird && itDontLookGood ) {
        Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:555-2368"));
        startActivity(intent);
    }

Linkify 소개#

Linkify는 RegEx 패턴 매칭(Pattern matching)을 통해 TextView 클래스( 그리고 TextView에서 파생된 클래스) 내에 하이퍼링크(HyperLink)를 자동으로 생성하는 도우미 클래스이다.

지정된 RegEx 패턴과 일치하는 텍스트는, 그 일치한 텍스트를 대상 URI로 사용해 암시적으로 startActivity(new Intent(Intent.ACTION_VIEW, uri))를 호출하는 클릭 가능한 하이퍼링크로 변환될 것이다.

네이티브 링크타입#

static 메서드 Linkify.addLinks는 linkify하기 위한 뷰 하나와, Linkify 클래스가 지원하고 제공하는 하나 이상의 기본 켄텐트 타입(Web_URLS, EMAIL_ADDRESS, PHONE_NUMBERS, ALL) 비트 마스크를 받아들인다.

http://developer.android.com/reference/android/text/util/Linkify.html#addLinks(android.widget.TextView, int)

  1. TextView textView = (TextView)findViewById(R.id.myTextView);
    Linkify.addLinks(textView, Linkify.WEBRULS|Linkify.EMAIL_ADDRESS);


  1. <TextView 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="@string/linkify_me"
        android:autoLink="phone|email"
    />

android:autoLink 속성을 사용하면 레이아웃 리소스 안에서 뷰를 링키파이할 수 있다.

 

커스텀 링크 문자열 만들기#

링키파이 문자열을 정의하려면, 하이퍼링크로 표시하고자 하는 텍스트와 일치하도록 새로운 RegEX 패턴을 만든다.

  1. int flags = Pattern.CASE_INSENSITIVE;
    Pattern p = Pattern.compiler("\\bquake[0-9]*\\b", flags);
    Linkify.addLinks(myTextView, p, "content://com.android.earthquake/earthquakes/");

또한 링키파이는 TransforFilter와 MachFilter 인터페이스를 지원한다.

이들은 대상 URI 구조와 매칭 문자열 정의에 대해서 추가적인 제어를 제공하며, 다음의 골격 코드에 보이는 것처럼 사용된다.

  1. Linkify.addLinks(myTextView, pattern, prefixWith, new MyMatchFilter(), new MyTransformFilter());

 

매치 필터 사용하기#

RegEx 패턴 매치에 추가 조건을 더하려면 MatchFilter에 acceptMatch메서드를 구현한다.

  1. public class MyMatchFilter implements MatchFilter {
        @Override
        public boolean acceptMatch(CharSequence s, int start, int end) {
            return (start == 0 || s.charAt(start - 1) != '!';
        }
    }

잠재적인 일치가 발견되면 acceptMatch가 호출되며, 매개변수로 일치 시작 지점과 끝 인덱스가 (탐색중인 전체 텍스트와 함께) 전달된다.

 

변형 필터 사용하기#

변형필터(Transform Fitler)는 여러분으로 하여금 링크 텍스트에 의해 생성된 암시적 URI를 수정하도록 함으로써 텍스트 문자열을 서시고하하는 데 더 많은 자유를 준다. 대장 URI로부터 링크 텍스트를 분리하는 것은 데이터 문자열을 사용자에게 표시하는 방식에 더 많은 자유를 준다. 대상 URI로부터 링크 텍스트를 분리하는 것은 데이터 문자열을 사용자에게 표시하는 방식에 더 많은 자유를 준다.

+ URI : http://ko.wikipedia.org/wiki/URI

+ URL : http://ko.wikipedia.org/wiki/URL

  1. ublic class MyTransformFilter implements TransformFilter {
        @Override
        public String transformUrl(Matcher match, String url) {
            // TODO Auto-generated method stub
            return url.toLowerCase();
        }
    }

 

액티비티 결과#

startActivity로 시작된 액티비티는 자신의 부모와 독립적이며, 종료할 때 어떠한 피드백도 제공하지 않을 것이다. 이에 대한 대안으로, 여러분은 액티비티를 본래부터 그의 부모에 연결된 서브 액티비티로 시작시킬 수 있다. 서브 액티비티는 종료할 떄 자신의 부모 액티비티 안에 있는 이벤트 핸들러를 호출한다. 서브 액티비티는 한 액티비티가 다른 액티비티를 위한 데이터 입력(사용자가 리스트에서 항목 하나를 선택하는 거소가 같은)을 제공하고 있는 상황에 제격이다.

서브 액티비티는 보통 액티비티와 같은 방식으로 만들어지며 또한 애플리케이션 매니페스트에 반드시 등록되어야 한다. 매니페스트에 등록된 모든 액티비티는 서브 액티비티를 오픈될 수 있다.

--> 주소록 보기(ContactPicker)

 

서브 액티비티 띄우기#

startActivityForResult 메서드는 startActivity와 상당 부분 비슷하게 동작하지만 한 가지 중요한 차이점이 있다.

  1. public static final int PICK_CONTACT = 1;
  2. Intent intent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts/"));
    startActivityForResult(intent, PICK_CONTACT);

실행할 액티비티를 결정하는 데 사용되는 인텐트 뿐만 아니라 요청코드도 전달한다. 이 값은 추후 결과를 리턴한 서브 액티비티를 유일하게 식별하는 데 사용된다.

 

결과 리턴하기#

finish를 호출하기 전에 setResult를 호출하여 호출 액티비티에 결과를 리턴한다.

setResult 메서드는 결과 코드와 인텐트로 표현된 결과 페이로드 이렇게 두 개의 매개변수를 취한다. 결과 코드는 실행중인 서브 액티비티의 "결과"다(대개 Activity.RESULT_OK나 Activity.RESULT_CANCELED 중 하나다).

결과로 리턴되는 인텐트는 콘텐트(연락처나 전호번호 혹은 미디어 파일 같은) 하나에 대한 URI와 부가 정보를 리턴하는 데 사용되는 엑스트라 컬렉션을 포함할 수 있다.

  1. public void onItemClick(AdapterView<?>parent, View view, int pos, long id) {
       //커서를 선택된 항목으로 이동한다.
       cursor.moveToPosition(pos);
       //행 id를 얻어온다.
       int rowId = cursor.getInt(cursor.getColumnIndexOrThrow("_id"));
       //결과 URI를 생성한다.
       Uri outURI = Uri.parse(data.toString() + rowId );
       Intent outData = new Intent();
       outData.setData(outURI);
       setResult(Activity.RESULT_OK, outData);
       finish();
  2. }

서브 액티비티 결과 다루기#

서브 액티비티가 종료된 그의 부모 액티비티에 있는 onActivityResult 이벤트 핸들러가 호출된다. 서브 액티비티로부터의 결과를 다루려면 이 메서드를 재정의한다. onActivityResult 핸들러는 다음과 같은 매개변수를 전달받는다.

  • 요청코드 : 현재 리턴되고 있는 서브 액티비티를 띄우는 데 사용된 요청 코드

  • 결과코드 : 서브 액티비티가 자신의 결과를 나타내기 위해 설정한 결과 코드 이는 어떠한 정수 값이라도 될 수 있지만, 대개는 Activity.RESULT_OK나 Activity.RESULT_CANCELED가 될 것이다.

  • 데이터 : 리턴된 모든 데이터를 담는 데 사용되는 인텐트. 이는 서브 액티비티에 목적에 따라, 전형적으로 리스트에서 선택된 데이터의 특정 부분을 나타내는 URI를 가진다.

네이티브 안드로이드 액션#

http://developer.android.com/reference/android/content/Intent.html

 

인텐트 필터를 이용해 암시적 인텐트 서비스하기#

http://developer.android.com/reference/android/content/Intent.html

안드로이드가 인텐트 필터를 해결하는 방법#

※ 인텐트 확인(Intent Resolution) : 어떤 액티비티를 시작시킬지 결정하는 과정

네이티브 안드로이드 애플리케이션 컴포넌트는 서드파티 애플리케이션과 정확히 같은 방식으로 인텐트 확인 과정에 참여한다. 이들(네이티브)이라고 보다 높은 우선 순위를 가지지는 않으며, 동일한 액션 요청을 서비스하는 인텐트 필터를 선언하는 새로운 액티비티로 완전히 대체될 수 있다.

인텐트 필터 매치에 반응하기#

애플리케이션 컴포넌트가 암시적 인텐트를 통해 시작되는 경우에는, 그가 수행할 액션과 이를 수행하기 위한 데이터를 얻을 필요가 있다. 컴포넌트 실행에 사용된 인텐트는 다음에 보이는 것처럼(대개 onCreate 메서드 내에서) getIntent 메서드를 호출해 얻는다.

인텐트의 데이터와 액션은 getData와 getAction 메서드로 얻는다.

  1. String action = intent.getAction();

  2. Uri data = intent.getData();

 

책임 떠넘기기#

startNextMatchingActivity 메서드를 이용해, 액션 처리의 책임을 다음 베스트 매칭 애플리케이션 컴포넌트로 넘길 수 있다.

  1. Intent intent = getIntent();
    if ( isAfterMidnight ) {
       startNextMatchingActivity(intnet);
    }

인텐트 필터에 기반을 두고 있는 인텐트 확인 과정의 능력을 뛰어 넘어, 사용 제한이라는 추가 조건을 컴포넌트에 추가할 수 있도록 해준다.

연락처 선택 예제#

이번 예제에서는 연락처 데이터에 대해 PICK_ACTION을 서비스하는 새로운 서브 액티비티를 만든다. 이는 연락처 데이터베이스에 있는 각각의 연락처를 나타내고, 사용자로 하여금 하나를 선택하도록 한 뒤, 그의 URI를 호출 액티비티에 리턴하고 종료한다.

  1. ContactPicker 액티비티를 포함하는 새로운 ContactPicker 프로젝트를 만든다. -> 한마디로 프로젝트를 만들라~~ 
  2. ListView 컨트롤 하나를 포함하도록 main.xml 레이아웃 리소스를 수정한다. 이 컨트롤은 연락처를 표시하는 데 사용될 것이다. 
  3. 텍스트 뷰 하나를 포함하는 새로운 listitemlayout.xml 레이아웃 리소스를 만든다. 이는 각 연락처를 리스트 뷰에 표시하는 데 사용될 것이다. 
  4. ContactPicker 액티비티로 돌아와, onCreate 메서드를 재정의하고 호출 인텐트로부터 데이터 경로를 얻어온다.

    1. 연락처 목록에 저장된 사람들에 대한 리스트 뷰 바인딩
    2. ItemClickListener를 리스트 뷰에 추가한다.
    3. onCreate 메서드를 닫는다.
  5. 애플리케이션 매니페스트를 수정해서, 액티비티의 intent-filter 태그를 연락처 데이터에 대한 선택 액션 지원을 추가하도록 바꾼다.
  6. 이것으로 서브 액티비티를 마무리한다. 이제 이를 테스트하기 위한 새로운 테스트 도구인 ContentPickerTester 액티비트를 만든다.
  7. ContentPickerTester의 onCreate 메서드를 재정의하고 버튼에 클릭 리스너를 추가하여, 버튼이 PICK_ACTION과 연락처 데이터베이스를 지정해 새로운 서브 액티비티를 암시적으로 시작시키도록 만든다.
  8. 서브 액티비티가 리턴하면, 그 결과를 이용해 선택된 지인의 이름으로 텍스트 뷰를 채운다.
  9. 이렇게 완성된 테스트 도구를 애플리케이션 매니페스트에 간단히 추가한다.

플러그인과 확장성을 위한 인텐트 필터 사용#

Menu 클래스로부터 사용 가능한 addIntentOptions 메서드는 이 메뉴에 의해 실행되는 데이터를 기술하는 인텐트를 지정할 수 있게끔 해준다. 안드로이드는 이 인텐트를 확인해 지정된 데이터와 일치하는 인텐트 필터에 지정된 모든 액션을 리턴한다. 새 메뉴 항목은 각각 일치하는 인텐트 필터의 레이블로 채워진 텍스트를 가지고 만들어진다.

애플리케이션에 익명 액션 제공하기#

액션을 다른 액티비티를 위해 사용할 수 있도록 만들려면, intent-filter 태그를 이용해 액션을 해당 액티비티의 매니페스트 노드 내에 알린다. 인텐트 필터는 자신이 수행하는 action과 자신이 수행될 수 있는 data를 기술한다. 후자는 이 액션이 사용가능해져야 하는 때를 결정하기 위한 인텐트 확인 과정 중에 사용될 것이다. category 태그는 반드시 ALTERNATIVE나 SELECTED_ALTERNATIVE 혹은 이둘 모두가 되어야만 한다. 메뉴 항목이 사용하는 텍스트는 android:label 속성에 의해 지어된다.

액티비티 메뉴에 익명 액션 통합하기#

메뉴에 메뉴 옵션을 런타임에 추가하기 위해서는 문제의 그 메뉴 객체에 대해 addIntentOption 메서드를 이용하여, 제공하고자 하는 액션을 위한 데이터를 지정하고 있는 인텐트 하나를 전달한다. 이는 일반적으로 액티비티의 onCreateOptionsMenu나 onCreateContextMenu 핸들러에서 처리될 것이다.

이 인텐트와 더불어 옵션 플래그, 호출 클래스 이름, 사용할 메뉴 그룹, 메뉴 ID 값을 채우고자 하는 메뉴에 대한 addIntentOptions  에 전달한다. 또한 추가 메뉴 항목을 만들기 위해 사용하고자 하는 인텐트의 배열을 지정할 수도 있다.

이벤트 방송을 위한 인텐트 사용#

인텐트는 시스템 수준의 메시지 전달 메커니즘으로서, 프로세스 경계를 가로질러 구조화된 메시지를 전송할 수 있다. 지금까지는 새로운 애플리케이션 컴포넌트를 시작시키기 위한 인텐트 사용에 관해 살펴봤지만, 인텐트는 sendBroadcast 메서드를 이용해 메시지를 컴포넌트 간에 익명으로 방송하는 데에도 사용될 수 있다. 애플리케이션 내에 브로드캐스트 수신자를 구현하여 이들 브로드캐스트 인텐트에 귀 기울이고 반응할 수 있다.

브로드캐스트 인텐트는 시스템이나 애플리케이션 이벤트의 리스너를 통지하는 데 사용되며, 애플리케이션 간의 이벤트 중심 프로그래밍 모델을 확장한다.

인텐트 방송은 애플리케이션을 보다 열려 있도록 만드는 데 도움을 준다. 인텐트를 이용해 이벤트를 방송함으로써, 애플리케이션을 수정하지 않고도 이벤트에 반응할 수 있도록 해준다. 애플리케이션 안에서 네이티브(혹은 서드파티) 애플리케이션을 대체 또는 향상시키거나 시스템 변경사항 및 애플리케이션 이벤트에 반응하기 위해 브로드캐스트 인텐트에 귀 기울일 수 있다(어떻게??). 예컨대, 걸려오는 전화 브로드캐스트에 귀 기울임으로써, 전화건 사람에 따라 벨소리나 벨소리 크기를 바꿀 수 있다.

인텐트로 이벤트 방송하기#

인텐트 방송은 간단하다. 애플리케이션 컴포넌트 안에서 방송하고 싶은 인텐트를 생성하고, sendBroadcast 메서드를 이용해 보내기만 하면 된다.

http://developer.android.com/reference/android/content/Context.html#sendBroadcast(android.content.Intent)

  1. public static final String NEW_LIFEFORM_DETECTED = "com.android.action.NEW_LIFEFORM";

인텐트 내에 데이터를 포함하기 원한다면, 인텐트의 data 프로퍼티를 이용해 URI를 지정할 수 있다. 또한 부가적인 기본 값들을 추가하기 위해 엑스트라를 포함할 수도 있다. 이벤트 중심 패러다임의 입장에서 고려해볼 때, 이 엑스트라 번들은 이벤트 핸들러 내에 있는 선택적인 매개변수와 같다.

  1. Intent intent = new Intent(NEW_LIFEFORM_DETECTED);
    intent.putExtra("lifeformName", lifeformType);
    intent.putExtra("logitude", currentlongitude);
    intent.putExtra("latidude", currentLatitude);
           
    sendBroadcast(intent);

브로드캐스트 수신자로 방송에 귀 기울이기#

브로드캐스트 수신자는 브로드캐스트 인텐트에 귀 기울이는 데 사용된다. 브로드캐스트 수신자를 활성화하려면, 코드나 애플리케이션 매니페스트를 통해 이를 등록할 필요가 있다. 브로드캐스트 수신자를 등록할 때는, 인텐트 필터를 이용해 그가 귀 기울이고 있는 인텐트가 무엇인지를 반드시 지정해야 한다.

새로운 브로드캐스트 수신자를 생성하려면, 다음의 코드에서 보이는 것처럼 BroadcastReceiver 클래스를 확장하고 onReceive 이벤트 핸들러를 재정의한다.

  1. import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;

    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
        }
    }

onReceive 메서드는 수신자를 등록하는 데 사용된 인텐트 필터와 일치하는 브로드 캐스트 인텐트가 수신될 때 실행될 것이다. onReceive 핸들러는 반드시 5초 이내에 마쳐야 하며, 그렇지 않으면 Application Unreponsive 다이얼로그가 표시될 것이다.

실행할 수신자를 위한 인텐트가 방송될 때, 등록된 브로드캐스트 수신자를 가진 애플리케이션이 꼭 실행되고 있어야 하는 것은 아니다.

브로드캐스트 수신자는 대체로 콘텐트를 업데이트하거나, 서비스를 띄우거나, 액티비티 UI를 업데이트하거나, 알림 관리자를 이용해 사용자에게 통지할 것이다.

애플리케이션 매니페스트에 브로드 캐스트 수신자 등록하기#

  1. <receiver android:name=".LifeformDetectedBroadcastReceiver">
        <intent-filter>
            <action android:name="com.android.action.NEW_LIFEFORM" />
        </intent-filter>
    </receiver>

코드로 브로드캐스트 수신자 등록하기#

코드로 브로드캐스트 수신자 등록을 제어할 수 있다. 이는 전형적으로 수신자가 액티비티에 있는 UI요소를 업데이트하는 데 사용되고 있을 때 이루어진다. 이 경우, 액티비티가 화면에 보이지 않을 때(혹은 활성 상태가 아닐 때) 브로드캐스트 수신자를 등록해제하는 것이 좋은 습관이다.

  1. //브로드캐스트 수신자를 생성해 등록한다.
    IntentFilter filter = new IntentFilter(NEW_LIFEFORM_DETECTED);
    LifeformDetectedBroadcastReceiver r = new LifeformDetectedBroadcastReceiver();
    registerReceiver(r, filter);

 브로드캐스트 수신자를 등록해제하려면 애플리케이션 켄텍스트 상에서 unregisterReceiver 메서드를 이용해 브로드캐스트 수신자 인스턴스를 전달한다.

  1. unregisterReceiver(r);

네이티브 안드로이드 브로드캐스트 액션#

http://developer.android.com/reference/android/content/Intent.html#ACTION_BOOT_COMPLETED

--> Reference에서  위에서처럼 #이후에 클래스에서 사용하는 상수로 액션등을 사용할 수 있다.

 

 

어댑터 소개#

  • 참고사항 :

    • Adapter : http://developer.android.com/reference/android/widget/Adapter.html

      : 어댑터는 데이터를 사용자 인터페이스 뷰와 바인드하는 브리징 클래스다(!?). 어댑터는 각 항목을 표현하는 데 사용되는 자식 뷰 생성과 하부에 놓인 데이터에 대한 접근 제공을 담당한다. 어댑터 바인딩을 지원하는 사용자 인터페이스 컨트롤은 반드시 AdapterView 추상 클래스를 확장해야 한다.

    • ArrayAdapter : http://developer.android.com/reference/android/widget/ArrayAdapter.html

      어댑터 뷰를 객체 배열에 바인드하는 일반적 클래스다. 기본적으로 ArrayAdapter는 각 객체의 toString  값을 레이아웃 내에 정의된 TextView 컨트롤에 바인드한다. => 상속받아 사용하는 자식 클래스들에서 필요에 따라서 getView 메서드를 오버라이딩하여 사용할 수 있다.

    • SimpleCursorAdapter : http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html

      뷰를 콘텐트 공급자 질의을 통해 리턴된 커서에 바인드한다. XML 레이아웃 정의를 지정한 뒤, 결과 셋의 각 열에 있는 값을 이 레이아웃에 있는 뷰에 바인드한다.

어댑터를 이용한 데이터 바인딩#

할 일 목록 ArrayAdapter 커스터 마이징#

  1. 할일 목록 프로젝트 열기, ToDoItem 클래스 생성

  2. ToDoList 클래스 열어 ArrayList와 ArrayAdapter 변수 타입을 문자열 대신 ToDoItem 객체를 저장하도록 수정한다. onCreate  메서드 수정이 필요함
  3. 액티비티를 실행
  4. 각각의 해야 할 일을 표시하기 위한 커스텀 레이아웃 만들기
  5. ToDoItem에 특화된 ArrayAdapter의 변형을 확장하는 새로운 클래스 ToDoItemAdapter를 만든다.
  6. 끝으로 ArrayAdapter 선언을 ToDoItemAdapter로 바꾼다.

SimpleCursorAdapter 사용하기#

SimpleCursorAdapter는 Cursor로부터 열을 커스텀 레이아웃 정의를 사용하는 리스트뷰(ListView)에 바인드할 수 있도록 해준다.

SimpleCursorAdapter는 현재 컨텍스트, 레이아웃 리소스, 커서, 그리고 사용할 열들의 이름을 담은 배열과 그에 대응하는 열의 데이터 값을 표시하기 위해 사용할 뷰의 리소스 ID를 담은(앞의 배열과 동일한 크기의) 배열을 전달함으로써 생성된다.

  1. SimpleCursorAdapter myAdapter;
    myAdapter = new SimpleCursorAdapter(this, R.layout.simplecursorlayout,
  2. myCursor, fromColumns, toLayoutIDs);

 

인터넷 리소스 소개#

띡 클라이언트(Thick-client) :

씬 클라이언트(Thin-client) : http://www.terms.co.kr/thinclient.htm

  • 대역폭 : 네이티브 애플리케이션을 만들어 데이터 업데이트 시에만 대역폭을 사용하도록 제한할 수 있다.
  • 캐싱 : 네이티브 애플리케이션은 살아있는 연결 없이도 가능한 많은 기능을 제공하기 위해 데이터를 캐시할 수 있다.
  • 네이티브 기능 : 온라인 데이터를 장치가 가진 하드웨어 기능과 결합할 수 있다.

인터넷 리소스에 접속하기#

http://developer.android.com/guide/topics/manifest/uses-permission-element.html

http://developer.android.com/reference/android/Manifest.permission.html

 

인터넷 리소스 이용 극대화#

  • WebView 위젯을 이용해 액티비티 안에 WebKit 기반 브라우저 컨트롤 포함 < - > API를 이용해 서버 프로세스와 직접 상호작용할 수 있다.
  • 데이터 추출을 위해 SAX나 javax 와 같은 자바 기반 XML 파서를 이용하여 원격 XML피드를 처리
  • 전송되는 데이터량을 제한해 사용자 경험을 최적화하고, 애플리케이션이 네트워크 정전과 대역폭 제한을 충분히 잘 다룰 수 있도록 견고하게 만들자.

    -> 어떻게!?

다이얼로그 소개#

  • 다이얼로그 계열 클래스 사용

    : 안드로이드는 범용 AlterDialog 클래스와 더불어, Dialog를 확장하는 전문적인 여러 클래스를 포함하고 있다.

  • 다이얼로그 테마가 적용된 액티비티

    : 평범한 액티비티에 다이얼로그 테마를 적용하여 다이얼로그 박스의 겉모습을 입힐 수 있다.

  • 토스트

    : 토스트는 일시적인 비 모달(non-modal) 메시지 박스로서, 사용자에게 이벤트를 통지하기 위하여 브로드캐스트 수신자와 백그라운드 서비스에 의해 종종 사용된다.

Dialog 클래스 소개#

http://developer.android.com/reference/android/app/Dialog.html

AlterDialog 클래스#

http://developer.android.com/reference/android/app/AlertDialog.html

AlertDialog 클래스는 가장 쓰임새가 많은 Dialog 구현 중 하나다. 이 클래스는 다이얼로그 박스가 사용되는 가장 흔한 경우 몇 가지를 위해 화면을 만들수 있도록 다양한 옵션을 제공한다.

  • 사용자에게 여러 개의 버튼 중 하나만 선택할 수 있는 형태로 최대 세 가지 옵션을 제공하는 메시지를 나타냄

  • 체크 버튼이나 라디오 버튼 형태로 옵션 목록을 제공

  • 사용자 입력을 위한 텍스트 입력 박스 제공

 

전문 입력 다이얼로그#

다이얼로그 사용과 관리#

필요할 때마다 매번 다이얼로그의 새로운 인스턴스를 생성하기보다는, 다이얼로그 박스 인스턴스를 지속하고 관리하기 위해 안드로이드는 액티비티 클래스에 onCreateDialog와 onPrepareDialog 이벤트 핸들러를 제공하고 있다.

액티비티를 다이얼로그로 사용하기#

  1. <activity android:name="MyDialogActivity"
             android:theme="@android:style/Theme.Dialog">
    </activity>

 

지진 뷰어 만들기#

==> 요건 패스, 해당하는 API 를 이용하여 정보를 얻을 수가 없다.

http://earthquake.usgs.gov

http://earthquake.usgs.gov/eqcenter/catalogs/1day-M2.5.xml

 

요약#

이번 장의 핵심은 애플리케이션 컴포넌트들을 바인딩하는 것이었다.

  • 인텐트(intent)는 애플리케이션과 다른 애플리케이션들 사이에 액션을 수행하고 이벤트를 신호하기 위한 의향을 전달할 수 있도록 해주는 다재다능한 메시징 시스템을 제공한다. 명시적 인텐트와 암시적 인텐트를 이용해 각각 액티비티를 실행시키는 방법을 배움.
  • 브로드캐스트 인텐트에 대해 살펴보면서, 이들을 이용해 장치 전체에 메시지를 전송하는 방법, 특히 시스템별 이벤트와 애플리케이션별 이벤트에 기반을 둔 이벤트 중심 모델을 지원하는 방법에 대해 알아봤다.
  • 또한 액티비티 간의 데이터 전달을 위해 서브 액티비티를 사용하는 방법과, 정보를 출력하고 사용자 입력을 손쉽게 하기 위한 다이얼로그 사용법을 배웠다.
  • 어댑터에 대해 살펴봤으며, 이를 하부 데이터를 비주얼 컴포넌트에 바인딩해봤다.
  • 특히, 리스트 뷰를 배열 리스트와 커서에 바인딩하기 위해 배열어댑터(ArrayAdapter)와 심플커서어댑터(SimpleCursorAdapter)를 사용하는 방법 살펴봤다.
  • 마지막, 인터넷 연결 이면에 있는 기본사항에 대해 배웠지만, 안되었다!!


다음장에서는 정보를 애플리케이션 내에 지속시키는 방법을 배울 것이다. 안드로이드는 애플리케이션 데이터를 저장하기 위해 파일, 간단한 환경설정, 그리고 모든 특성을 갖춘 관계형 데이터베이스(SQLite) 등을 포함한 여러 메커니즘을 제공한다.

 

보충 - 안드로이드 관련 근황#

 

이 글은 스프링노트에서 작성되었습니다.

'Programming' 카테고리의 다른 글

[Velocity] velocity.properties  (0) 2010.03.13
Velocity 설정법  (0) 2010.02.21
나도 Java Champion 될 수 있을까?  (0) 2010.01.09
[펌] 2010년 전략 기술 톱 10  (0) 2009.10.26
잘 만들어진 코드  (0) 2009.09.07

+ Recent posts