블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 


안드로이드 인테트를 통해서 액티버티 생성하기


조대협(http://bcho.tistory.com)


요즘 일이 바쁘고 하는 역할도 바뀌어서 기술보다는 관리나 스크럼에 대한 글들을 읽고 공부하다보니, 반대적으로 기술에 대한 포스팅이 줄었다. 이래서는 안되겠다 싶어서, 어떤 부분을 봐야 할까 고민하다 보니 빅데이타와 앱 개발 기술쪽을 봐야겠다가 시작은 했는데, 막상 진도는 잘 안 나가고 있어서. 앱팀을 운영하고 있으니, 말이라도 통할려면 기본이라도 알아야 겠다 해서 안드로이드 앱쪽을 공부하고 있는데, 일단 해놓은 내용이라고 까먹지 않으려면 정리해놔야겠다는 생각에 간단하게 포스팅한다.


본 문서의 내용은 https://developer.android.com/training/index.html 를 기반으로 작성하였다. (문서에 있는데로 하면 생각보다 안되느 부분이 많다. 문서를 업데이트 하지 않아서 그런것 같은데). 

해당 프로그램은 화면에서 문자열을 입력 받아서, SEND라는 버튼을 누르면 다른 화면에서 입력 받은 문자열을 다른 화면에서 보여주는 예제이다 



MyActivity라는 액티비트에서 텍스트 박스를 통해서 문자열을 입력받고, SEND 버튼을 누르면, 텍스트 박스내의 문자열을 읽어서 Intent로 만들어서 DisplayActivity라는 액티비티로 전달하면 해당 문자열을 출력하는 내용이다.



먼저 인텐트의 개념에 대해서 이해할 필요가 있는데, 인텐트는 서로 다른 컴포넌트 간에 이벤트를 전달할 수 있는 개념이다. 위의 그림에서와 같이 MyActivity에서, DisplayActicity로 액티비티간에 출력할 문자열을 보내는것과 같은 이벤트이다. 유닉스의 IPC(Inter process call)과 같은 개념으로 생각을 하면된다. 

인텐트에 대한 자세한 내용은 https://developer.android.com/guide/components/intents-filters.html 를 참고하기 바라며, 나중에 다시 다루도록한다.


먼저, 문자열을 입력받을 화면을 작성한다. 안드로이드 스튜디오에서, 다음과 같은 레이아웃으로 작성을 한다. 



다음으로 버튼을 눌렀을때, 인텐트를 만들어서 보내기 위해서 버튼을 눌렀을때 실행되는 메서드를 정의하여 버튼 이벤트와 연결한다.

    public void sendMessage(View view){


        EditText editText = (EditText)findViewById(R.id.editText);

        String message = editText.getText().toString();


        Intent intent = new Intent(this,DisplayMessageActivity.class);

        intent.putExtra("com.example.terry.basicintentsample.MESSAGE",message);

        startActivity(intent);

    }


이 메서드는 새로운 인텐트를 생성하여 DisplayActivity라는 액티비티 클래스로 보내지는 인텐트가 된다.

인텐트를 통해서 보내지는 데이타는 “com.example.terry.basicintentsample.MESSAGE” 문자열을 키로 해서, EditText 텍스트 문자열 박스에서 읽어도 문자열을 값으로 해서 putExtra메서드를 이용해서 인텐트에 바인딩 된다. 

이 인텐트는 startActivity를 통해서 DisplayActivity 액티비티를 새롭게 시작하면서 같이 전달이 된다. 

위와 같이 코드를 작성하여,액티버티 뷰를 정의한 activity_my.xml에서 다음과 같이 버튼이 눌렀을때 작성한 “sendMessage”메서드가 호출되도록 정의 한다.

        <Button

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="SEND"

            android:id="@+id/button"

            android:layout_weight="1"

            android:onClick="sendMessage" /


인텐트를 만들어서 보내는 부분이 끝났으면, 이제 인텐트를 받아서 출력하는 부분을 구현해보도록 하자.

안드로이드 스튜디오에서,  새로운 액티비티를 생성한다.




생성된 액티비티에는 간단하게, “myMessage”라는 아이디로 TextView 하나만 배치 시킨다.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"

    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    android:paddingBottom="@dimen/activity_vertical_margin"

    tools:context="com.example.terry.basicintentsample.DisplayActivity">


    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:id="@+id/myMessage" />


</RelativeLayout>


다음으로 OnCreate 메세지에 다음과 같은 코드를 추가한다.

    @Override 

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);


        // Render View first

        setContentView(R.layout.activity_display);


        // Get the message from the intent

        Intent intent = getIntent();

        String message = intent.getStringExtra("com.example.terry.basicintentsample.MESSAGE");

        TextView textView = (TextView)findViewById(R.id.myMessage);

        textView.setText(message);


    }

위의 코드는 인텐트에서 문자열을 받아서 “myMessage”라는 id의 텍스트 뷰에 그 문자열을 출력하는 코드이다.

출력전에, setContentView를 먼저 호출해야 하는데, View를 렌더링한 후에 myMessage TextView가 생성된다. 

다음으로 getIntent() 메서드를 이용하면, 인텐트를 받을 수 있고, getStringExtra메서드를 이용해서 “com.example.terry.basicintentsample.MESSAGE” 키로 문자열을 받아서 TextView에 setText로 세팅한다.




안드로이드 Activity Lifecycle (액티버티 생명주기)와

, Back Stack & Task


조대협 (http://bcho.tistory.com)


Back Stack

Activity의 라이프 사이클 개념을 이해하기 전에, 먼저 BackStack이라는 개념을 이해해야 한다.
안드로이드 애플리케이션은 모바일 애플리케이션의 특성상 하나의 화면, 즉 Activity만 화면에 활성화가 되게 된다. 활성화 된 화면에서 작업하다가, Back 버튼등을 눌러서 이전화면으로 돌아갈 수 있는데, 이런 돌아가는 구조를 지원하기 위해서, 내부적으로 화면이 전환이 되더라도 기존의 화면을 없애는것이 아니라 메모리에 저장해놨다가, 돌아갈때 저장된 화면을 띄워 주는 구조가 된다
이런 구조를 구현하기 위해서 내부적으로 BackStack이라는 구조를 사용하는데, 각각의 화면이 Activity이기 때문에, 화면이 전환될때 마다, 그 Activity를  BackStack안에 저장한다. 그리고, Back 버튼등으로 돌아기기를 할 경우에는 Stack에서 하나씩 꺼내서 이전 화면으로 전환을 한다

아래 그림을 보자, 
  • 처음에 Activity 1 화면이 활성화 되었다.
  • 다음에 Activity 2가 실행되면, Activity 1이 BackStack에 저장된다.
  • 그 다음에 Activity 3이 실행되면, Activity 2가 BackStack에 추가적으로 저장되는 것을 볼 수 있다.
  • 이때 Activity 3가 Back 버튼등에 의해서 종료되면, Activity 3는 Destroy 되고, Back Stack에 있던 Activity2 가 활성화 된다.





Task

A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (the back stack), in the order in which each activity is opened.

BackStack의 개념을 대략적으로 이해한후에, Task라는 개념을 이해하는게 좀 어려웠는데, Task하는 하나의 BackStack이라고 생각하면 된다. 그런데 왜 굳이 이 Task라는 개념을 사용하느냐? 아직은 잘 모르겠지만, 글들을 읽어보면 일단 키 포인트는 안드로이드 애플리케이션의 Activity는 서로 다른 application간에 공유가 가능하다.
즉, 내가 A라는 애플리케이션을 수행하다가, SNS 공유와 같은 기능을 사용할때, SNS 애플리케이션 B의 Activity들을 불러올 수 있다.  또는 이메일 클라이언트에서, 사진앱의 activity들을 불러서, 첨부 사진을 선택할 수 있다.

그렇다보니, 하나의 Activity는 동시에 여러개의 애플리케이션에 의해서 사용될 수 있기 때문에, 다른 개념을 사용하는데, 이를 Task 라고 한다. 현재 실행중인 애플리케이션의 Activity Stack은 이 Task라는 곳에 저장이 되게 된다.
(일종의 instance 개념과 유사한듯)


Activity의 라이프 사이클

Activity는 사용자와 Interaction이 있는 UI를 처리하는 컴포넌트로 다음과 같은 생명 주기를 갖는다. 각 주기마다 이벤트에 의해서 호출되는 함수들을 정리하면 다음과 같다.





  • OnCreate : 맨 처음 랩이 처음 실행되었을때, 실행되는 메서드로 UI 컴포넌트등을 로딩하고, Listner를 바인딩하고, 초기 데이타를 로딩하는 등의 초기화 작업을 수행한다.
  • OnStart : UI가 화면에 보이기 전에 바로 호출된다. UI가 로딩 된다고 해도, 사용자로 부터 Input을 받을 수 는 없다
  • OnResume : UI 로딩이 끝난후, 사용자 Input (Interaction)이 시작되기 전에 호출된다. 이 함수들이 다 호출되고 나면, 애플리케이션은 실행 가능 상태인 “Activity Running” 상태가 되며, UI도 모두 로딩되고, 사용자로 부터 입력을 받을 준비도 끝난다.
  • OnPause : 이 상태에서 만약에 다른 Activity 화면이 올 경우, OnPause가 호출된다.
    정확한 상태 정의는 “보이기는 하지만 사용자가 Interaction을 할 수 없는 상태” 정도로 정의할 수 있다. 이런 상태가 어떤 상태인가 하면, 다이얼로그등과 같은 다른 액티버티가 앞에 떠서 사용자 Interaction을 수행하는 상태이다 그러나 기존의 Activity는 그대로 뒤에 떠 있지만, 뒤에 떠 있는 activity 는 사용자 Interaction을 받지 못하는 상태이다.
 




이 때 사용중인 쓰레드 정리, 데이타 저장등을 수행하거나 또는 포커스를 잃은 화면이기 때문에 애니메이션등을 정지해야 한다.
  - 이때 다시 해당 Activity로 돌아가게 되면 OnResume으로 다시 돌아가서, 화면을 다시 호출하게 된다.
  - 화면이 보이지 않는 상태에서 만약에 메모리가 부족하게 되면 안드로이드 시스템에 의해서 이 단계에서 자동으로 정지(Killed) 될 수 있다. Killed 된 상태에서 다시 그 화면으로 돌아가게 되면 다시 onCreate로 돌아가서 앱을 처음부터 다시 시작하게 된다.

  • OnStop : 액티버티가 더이상 사용자에게 보여지지 않을때 호출된다. 
  • OnDestroy : 액티버티가 소멸될때 호출된다. 

Activities in the system are managed as an activity stack. When a new activity is started, it is placed on the top of the stack and becomes the running activity -- the previous activity always remains below it in the stack, and will not come to the foreground again until the new activity exits.

An activity has essentially four states:

  • If an activity in the foreground of the screen (at the top of the stack), it is active or running.
  • If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent activity has focus on top of your activity), it ispaused. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations.
  • If an activity is completely obscured by another activity, it is stopped. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere.
  • If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.

각 단계별로 실제로 돌아가는 걸 볼래면, 한번 만들어보고 이벤트 걸고 추적해봐야 겠다.





안드로이드 프로그래밍 구조의 기본


조대협 (http://bcho.tistory.com)


해당 포스팅은 https://class.coursera.org/androidpart1-005/lecture/13 의 내용을 바탕으로 정리하였습니다


안드로이드 애플리케이션의 주요 구성 요소

안드로이드 애플리케이션을 이루는 주요 구성 요소는 크게 다음 4가지이다.


  • Activity : 가장 메인이 되는 컴포넌트로, 모바일 앱의 특성상, 모바일앱은 하나의 UI가 떠서 사용자로 부터 입력을 받고, 출력을 담당한다. 즉 하나의 화면 인터페이스에 해당한다고 보면된다.
  • Service : 백그라운드에서 도는 컴포넌트로 UI가 없이 동작한다. 가장 쉬운 예로 음악 플레이 처럼 화면이 없는 상태에서 백그라운드로 도는 케이스가 가장 대표적인 예이다.
  • BroadCastReceiver : 이벤트를 처리하는 컴포넌트로, 안드로이드의 Intent를 받아서 처리한다. 이 Intent는 Pub/Sub형태로 바인딩되며, 특정 intent가 발생하면, 이를 subscribe하는 BroadCastReceiver가 이를 받아서 처린한다.
  • ContentsProvider : ContentsProvider는 일종의 Database를 추상화 해놓은 개념으로 , 단순히 데이타를 저장하는 것 뿐만 아니라, 저장된 데이타를 다른 앱간에 공유하는 기능도 지원한다.
안드로이드 빌드 & 배포 프로세스
안드로이드 프로젝트는 어떻게 빌드 및 패키징 되서, 단말에서 동작할까.
안드로이드 프로젝트를 빌드하게 되면 코드 컴파일 작업이 수행되고, 컴파일 후에는 컴파일된 코드 이외에 리소스를 포함하여 *.apk라는 파일로 패키징이 된다.
  • 패키징된 파일안에는 코드를 컴파일한 내용인 *.dex 파일이 생성되고
  • 컴파일된 리소스 파일이 *.arsc라는 파일로 저장된다.
  • 그리고 컴파일 되지 않은 리소스 (무엇일까?)가 같이 저장되고
  • 안드로이드 애플리케이션의 설정을 지정하는 AndoridManifest.xml 파일이 저장된다.

출처 : http://developer.android.com/tools/building/index.html


다음으로, 이  apk 파일을 싸이닝을 한다. 싸이닝(Signing)이란, 키를 이용하여 이 APK에 서명을 하는 작업으로, 이 APK 가 변조되었을 경우 서명 값이 틀려지게 되는데, 싸이닝은 apk가 타인에 의해서 위변조 되는 것을 방지하고, 내가 이 애플리케이션을 만들었다는 표시를 하는 과정이다. (나중에 애플리케이션이 업데이트가 되면 같은 키로 싸이닝을 해서, 내가 만든 애플리케이션임을 증명한다.)