Android App Components -1
1. Activity
1.1 소개
- Android 4개의 컴포넌트 중의 하나.
- 사용자 인터페이스 화면을 의미한다.
- UI 컴포넌트를 화면에 표시하고 시스템이나 사용자의 반응을 처리한다.
- 하나의 어플리케션은 여러 Activity를 가질 수 있고, 어플리케이션이 실행되었을 때 가장 먼저 실행되는 Activity를 'Main Activity'라고 한다.
- Activity의 전환으로 생기는 사항은 'Back Stack'이라는 "last in, fist out" stack mechanism이라고 한다.
- AndroidManifest에 등록해야된다.
<activity android:name=
".view.activities.IntroActivity"
android:screenOrientation=
"portrait"
/>
1.2 Creating an Activity
- Activity를 생성하기 위해서는 Activity클래스를 상속받아야 한다.
- Activity LifeCycle에 따라 다양한 상태전환이 이루어지기 때문에 각 상태에 해당되는 콝백 메소드를 재정이 해줘야 한다.
- onCreate() : UI에 관한 layout을 정의하는 setContentView()를 이 부분에서 사용해야 한다.
public class MyActivity extends Activity{ @Override public void onCreate(Bundel savedInstanceState){ super .onCreate(savedInstanceState); setContentViewe(R.layout.main); // main.xml 파일의 레이아웃을 이 activity에 적용 //여기에 자신이 작업할 추가적인 내용을 구성한다. } } |
1.3 Starting an Activity
- Activity에서 다른 Activity를 생성하려면 Intnet를 생성하고 startActivity() 메소드를 사용한다.
- 생성될 Intent에 실행시키고자 하는 Activity의 정보를 명시해야 한다.
- Explicit Intent
- 동일한 어플리케이션 내에 존재하는 Activity를 호출하거나 반드시 해당 Activity를 호출해야 할 경우 Activity Class명을 사용하여 Activity를 시작한다.
- Intent 클래스의 생성자 중에서 첫번째 인자에 Intent 객체를 생성하여 사용하는 Context를 명시, 두 번째 인자에는 사용하고자하는 Component 클래스를 명시한다.
Intent intent =
new
Intent(
this
, NextActivity.calss);
startActivity(intent);
- Implicit Intent
- 어떤 Activity가 실행될지 직접적으로 결정할 수 없을 경우(예, 이메일, Text 메시지 보내기)
- 자신이 원하는 action을 명시하여 Activity를 실행한다.
Intent intent =
new
Intent(Intent.ACTION_SEND);
// Email을 보내는 행동
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
- Explicit Intent
1.4 Starting an Activity for a result
- Activity를 수행한 뒤 결과를 반환 받아야할 경우 사용한다. (예, 카메라 어플)
- startActivity() 메소드 대신, startActivityForResult() 메소드를 사용하고 onActivityResult() 콜백 메소드를 재정의한다.
- onCactivityResult()메소드에 전달되는 3가지 인자.
- resultCode : startActivityForResult()의 두번째 인자와 동일하다. 여러 개의 Activity를 수행시킨 경우 이 값으로 어떤 Activity의 결과값인지 구별할 수 있다.
- resultCode : 실행결과값이 성공으로 받았는지의 여부를 확인한다.
- data : Activity의 구체적 실행 값이다.
private
void
pickContact(){
// Create an intent to "pick" a contact, as defined by the content provider URI
Intent intent =
new
Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT_REQUEST);
}
@Override
protected
void
onActivityResult(
int
requestCode,
int
resultCode, Intent data){
// if the request went well (OK) and the request was PICK_CONTACT_REQUEST
if
(resultCode ==Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST){
// Perform a query to the contact's content provider for the contact's name
Cursor cursor = getContentResolver().query(data.getData(),
new
String[] {Contacts.DISPLAY_NAME},
null
,
null
,
null
};
if
(cursor.moveToFirst()){
// Ture if the cursor is not empty
int
columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
String name = cursor.getString9columnIndex);
// Do something with the selected contact's name...
}
}
}
1.5 Activity LifeCycle
- onCreate()
- Activity가 생성될 때 호출되는 메소드
- 화면 Layout을 구성하고 각정 object들을 초기화하는 단계
- onStart()
- Activity가 사용자에게 보여줄 준비가 되었을 때 호출됨
- onResume()
- Activity가 사용자에게 보여지고 사용자 입력을 처리할 수 있는 단계
- onPause()
- Focus를 잃고 이전의 Activity가 resume 되기 전, 데이터를 저장하고 cpu 소비하는 작업을 중단함
- onDestory()
- 안드로이드 시스템 내의 Activity가 존재하지 않는 단계
2. Service
2.1 소개
- 사용자 인터페이스 화면이 아니라 Background로 실행되는 component(예, mp3)
- startService() : service를 시작할 때 사용하는 메소드
- bindServicee() : 어플리케이션 컴포넌트와 연결을 할 때 사용하는 메소드
- 두가지의 Service
- 백그라운드 작업(local Service)
- 사용 메서드 : onStartCommend (Intent intent, int flags, int startId)
- 호출 메서드 : CompornetName stratService (Intent service)
- 중지 메서드 : stopService (Intent service)
- 원격 호출 인터페이스
- 사용 메서드 : onBind (Intent intent)
- 호출 메서드 : bindService (Intent service, ServiceConnection conn, int flags)
- 중지 메서드 : unbindService (ServiceConnection conn)
- 백그라운드 작업(local Service)
- AndroidManifest에 등록해야된다.
<service android:name=
".controller.MusicDownloadController"
android:label=
"@string/download_service_name"
/>
2.2 Service LifeCycle
startService()를 시작하면 음악을 background 형태로 running하는 것이다.
사용자가 음악을 들으며 이전곡, 다음곡 등으로 제어를 할 때
bindService()가 호출이 되고 onUnbind()가 되면 다시 Service running 형대가 된다.
2.3 AIDL(Android Interface Definition Language)
- Service가 실행하고 있는 process가 아닌 별개의 process에서 API를 호출하고자 할 때는 IBinder와 AIDL을 사용해야한다.
- AIDL을 통해 IPC(InterProcess Communication)가 가능하다.
- AIDL을 사용해서 bind 하는 방법
- .aidl 파일 생성
- 인터페이스 구현
- 인터페이스에서 client 제시 : service 구현 및 onBind() 재정의
.aidl 파일 생성
// IRemoteService.adil package com.example.android: //Declare any non-default types here with import statements Inteface IRemoteService{ /**Request the process ID of this service, to do evil things with it. */ int getPid(); /** Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes( int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); } |
Interface 구현
private final IRemoteService.Stub mBinder = new IRemoteService.Stub(){ public int getPid(){ return Process.myPid(); } public void basicTypes( int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString){ // Does nothing } } |
Interface에서 client제시
public class RemoteService extends Service{ @Override public void onCreate(){ super .onCreate(); } @Override public IBinder onBinder(Intent intent){ // Return the interface return mBinder; } private final IRemoteService.Stub mBinder= new IRemoteService.Stub(){ public int getPid(){ return Process.myPid(); } public void basicTypes( int anInt, long aLong, boolean , aBoolean, float aFloat, double aDouble, String aString){ // Does nothing } }; } IRemoateService mIRemoteService; private ServiceConnection mConnection = new ServiceConnection(){ // Called when the connection with the service is estabilished public void onServiceConnected(ComponentName className, IBinder service){ // this gets an instance of the IRemoteInterface, which we can use to call on the service mIRemoteService = IRemoteService.Stub.asInerface(service); } // Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className){ Log.e(TAG, "Services has unexpectedly disconnected" ); mIRemoteService = null ; } }; |
2.4 Messaenger
- AIDL 없이 IPC를 할 수 있도록 Android에서 제공해주는 MEssenger 클래스이다.
- Messanger는 Handler 클래스를 상속받아 구현하며 Handler의 인스턴스를 가지고 있다.Message를 수신할 Service 쪽의 onBind()메소드
public
class
MessengerService
extends
Service{
Messenger mMessenger =
new
Messenger(
new
Handler(){
@Override
public
void
handleMessange(Message msg){
super
.handleMessage(msg);
}
});
@Override
public
IBinder onBind(Intent intent){
return
mMessenger.getBinder();
}
}
Service와 연결할 Client 코드
public static class MessengerClient extends Activity{ Messenger mService = null ; private ServiceConnection mConnection = new ServiceConnection(){ public void onServiceConnected(ComponentName className, IBinder service){ mService = new Messenger(service); } public void onServiceDisconnected(ComponentName className){ mService = null ; } }; @Override protected void onCreate(Bundle savedInstanceState){ super .onCreate(savedInstanceState); bindService( new Intent(MessengerClient. this , MessengerService. class ), mConenction, Context.BIND_AUTO_CREATE); } } |
3. Intent & IntentFilter
3.1 Intent 소개
- 어플리케이션 컴포넌트에서 다른 어플리케이션 컴포넌트를 실행시킬 때 필요한 객체
- 어플리케이션 컴포넌트에 action, data를 전달하는 메시지 객체
- Intent 객체가 가지고 있는 정보
- Component name, Action, Data, Category, Extras, Flags
- 두 가지의 Intent
- Explicit
- 실행할 어플리케이션 컴포넌트의 이름이 명시된 Intent
- Implicit
- 다른 어플리케이션의 컴포넌트를 실행할 때 사용
- 클래스 이름 대신에 action 이름으로 명시된 Intent
- Explicit
3.2 Intent 객체가 가지고 있는 정보
- Component name : 호출할 Activity, Service나 BR(Broadcast Receiver) 등의 이름을 나타낸다.
- Action : Intent를 통해 수행할 동작을 지정하거나 특정상태를 의미한다. Intent는 *하나의 action*만 가진다.
Constant Target Component Action android.intent.action.ACTION_CALL Activity 전화를 건다 android.intent.action.ACTION_EDIT Activity 데이터를 편집한다 android.intent.action.ACTION_MAIN Activity task의 첫 Activity로 시작한다 android.intent.action.ACTION_BATTERY_LOW BR 베터리 수준이 낮음을 뜻한다 android.intent.action.ACTION_SCREEN_ON BR 단말기 화면이 켜졌음을 의미한다 - Data : Intent는 대상 Component에서 처리할 Action 뿐 아니라 Data도 전달 할 수 있다. Data형태는 URI형태로 구성되며 종류에 따라 type이 다르다.
종류 형태 타입 의미 URL http://naver.com X 사이트 주소 사진, JPEG Content://media/external/images/media/1 image/jpeg 이미지 음악 Content://media/external/images/audio/1 audio/mp3 오디오 전화번호 Tel:01028749769 X 전화번호 좌표 geo::37.111111-222.333333333 X 특정 지역 좌표 - Category : Action과 함께 component의 특징을 나타내는 항목. Action과 다르게 Intent에 *여러개의 category*를 가질 수 있다.
Constant Category android.intent.category.HOME 홈화면을 표시한다 android.intent.category.LAUNCHER Activity가 어플리케이션의 런처에 표시된다. android.intent.category.PREFERENCE 환경설정을 표시한다 - Extras : Intent를 통해 component를 호출하거나 메시지를 보내면서 URI형태가 아닌 data를 전달할 때 사용한다.
Extras는 Bundle Object에 +Key-value pair+를 통해 저장된다.
3.3 Intent Filter 소개
- 어플리케이션 component가 받고자 하는 Intent가 무엇인지 확인하는 수단
- Intent Filter의 구성요소
- action
- data(URI, data type)
- category
- AndroidManifest에 등록한다.
<activity android:name=
".view.activities.HomeActivity"
android:launchMode=
"standard"
android:screenOrientataion=
"portrait"
>
<intent-filter>
<action android:name=
"android.intent.action.MAIN"
/>
<category android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
4. AndroidManifest
4.1 소개
- XML문서 형식의 어플리케이션 명세서
- 안드로이드 어플리케이션의 이름, 버전, 구성요소, 권한 등을 설정할 수 있다.
- 어플리케이션의 java package 이름을 지정
- 어플리케이션의 components 지정
- 어떤 프로세스가 어플리케이션의 작동을 하는지 결정
- Permission 선언 및 정의, 어플리케이션에 요구되는 최소 API레벨 및 연결되어야하는 라이브러리 지정
permission ACCESS_FINE_LOCATION GPS 위치 추적기능이 필요한 권한 BLUETOOTH 블루투스를 연결할 수 있는 권한 CALL_PHONE 다이얼로 전화를 걸 수 있또록 허락하는 권한 CAMERA 내장 카메라 접근 권한 INTERNET 인터넷 접속 권한 RECEIVE_SMS 문자메시지 수신 기능을 허락하는 권한 SEND_SMS 문자메시지 전송 기능을 허락하는 권한 VIBRATE 진동 기능을 허락하는 권한
AndroidManifest 예제
<?xml version= "1.0" encoding= "utf-8" ?> <manifest xmlns:android= "http://schemas.android.com/apk/res/android" package = "com.example.helloworld" // 응용프로그램의 패키지 이름 android:versionCode= "1" // 응용프로그램의 버전 부호, 업데이트 할 때마다 버전 부호를 증가시켜야 함 android:versionName= "1.0" > <uses-permission android:name= "android.permission.INTERNET" /> //권한 설정요소 <application android:icon= "@drawable/icon" android:label= "@string/app_name" > <activity android:name= ".HelloWorldActivity" android:label= "@string/app_name" > <intent-filter> <action android:name= "android.intent.action.MAIN" /> <category android:name= "android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion= "7" /> </manifest> |
AndroidManfiest.xml 속성
<?xml version=“ 1.0 ” encoding=“utf- 8 ”?> <manifest> => 응용 프로그램의 패키지 이름 및 버전 정보를 설정 <uses-permission /> // 응용프로그램에 필요한 권한 등록 <permission /> // 응용 프로그램이 다른 응용 프로그램에게 허락하는 권한들을 등록 <instrumentation /> // 응용 프로그램과 시스템 리소스와의 상호 작용을 모니터링하는 유효 <uses-sdk /> // 응용 프로그램을 어느 버전의 안드로이드 환경에서 사용할 수 있는지 설정 <uses-configuration /> // 응용 프로그램에 필요한 하드웨어/소프트웨어 입력 구성을 정의 <uses-feature /> // 응용 프로그램에서 사용되는 특정 feature를 설정 <supports-screen /> // 응용 프로그램에서 지원하는 화면 크기를 설정 <application> // 응용 프로그램의 이름과 아이콘을 설정 <activity> // 응용 프로그램의 모든 activity를 각각 하나의 <activity> 요소로 등록 <intent-filter> <action /> <category /> <data /> </intent-filter> </activity> <service> </service> // service 등록 <receiver> </receiver> // broadcast receiver 등록 <provider> </provider> // content provider 등록 <uses-library /> // 지도 서비스처럼 추가로 연동되는 다른 패키지들을 링크 </manifest> |