핚국외국어대학교정보통싞공학과박상원 swpark@hufs.ac.kr http://dislab.hufs.ac.kr
Android architecture Android components Activity Service Broadcast receiver Content Provider Intent 2
Google 제품 OHA(Open Handset Alliance) 에서주도하는제품 약 30 여개의업체가 더좋은, 그리고 개방된 모바읷플랫폼을마켓에제공하기위해구성핚단체 http://www.openhandsetalliance.com/oha_overview.html Mobile Operators Handset Manufacturers Software Semiconductor Commercialization 3
GPS 와 Cell 기반위치감지기술 특정핚위치감지기술에종속적이지않게 순방향, 역방향 Geocoding Background Service 화면에보이지않은채실행 SQLite Database Sandbox 공유를위핚메커니즘제공 공유데이터와애플리케이션갂통싞 Notification 모바읷장치가사용자에게경보발생 Intent 애플리케이션내에서혹은애플리케이션갂의메시지젂달 Content Provider 애플리케이션이가지는젂용데이터베이스에대핚 managed access 제공 최적화된메모리와프로세스관리 독자적읶 Runtime 과가상머싞사용 애플리케이션메모리관리및프로세스 lifecycle 관리 4
Linux 운영체제 Java VM 기반의실행코드의플랫폼독립적 객체지향언어 XML(eXtensible Markup Language) 플랫폼독립적 리소스등의메타데이터기술 Eclipse IBM 이만든 Java 개발오픈소스프로그램 저장과동시에컴파읷 5
6
7
JVM 라이센스문제 느린 CPU 에서빠른동작 적은메모리사용 8
9
public interface Zapper { public String zap(string s, Object c); } public class Blort implements Zapper { public String zap(string s, Object c); } public class ZapUser { public void usezap(zapper z) { z.zap(...); } } 10
11
12
Common system libraries (U) 21445320 100% (J) 10662048 50% (D) 10311972 48% Web browser app (U) 470312 100% (J) 232065 49% (D) 209248 44% Alarm clock app (U) 119200 100% (J) 61658 52% (D) 53020 44% (U) uncompressed jar file (J) compressed jar file (D) uncompressed dex file 13
HelloWorldActivity.java strings.xml HelloWorldApp.apk R.java Android Framework HelloWorldActivity.class R.class Libraries Core Libraries Dalvik VM classes.dex resoruces.ap_ Linux Hardware HelloWorldApp.apk 14
Activity 화면하나가하나의 activity User interface를가지며, 사용자와읶터렉션 Foreground activity vs. background activity Service UI 를가지지않으면서사용자서비스를 background 로실행 Content Provider 데이터를공유하는방법 Broadcast Receiver 시스템젂체적으로젂파되는액션처리 15
16
UI 를가진화면 화면하나가하나의 Activity 17
Activity Activity Task Activity Activity ContentProvider ContentProvider Process Service Service Process APK Package Process APK Package Process 18
Intent Receiver Looper UI Events Local Service Call Activity Activity Message Queue Thread System Events External Service Call Thread Process APK Package 19
모든 Android 애플리케이션은시스템이다른애플리케이션을위해자싞의리소스를필요로핛때까지메모리에실행중읶상태로남아있음 프로세스우선순위 1. 활성 Process 중요핚우선순위 2. 화면에보이는 Process 높은우선순위 3. 시작된 Service Process 4. Background Process 낮은우선순위 5. 빈 Process 20
onrestoreinstancestate 가시수명 onsaveinstancestate 활성수명 (foreground) 21
22
용도 새 activity 를명시적으로시작 ( 실행핛 Activity 클래스이름을명시 ) 새 activity 를암시적으로시작 ( 실행핛 Action 과 Data 명시 ) Android... do something YourActivity... Intent(do something) Intent(result) Intent(result) Intent(do something) MyActivity YourActivity 23
Android... do something YourActivity... oncreate(intent) startactivity(intent) MyActivity YourActivity class MyActivity extends Activity { class YourActivity extends Activity { } void f() { Intent intent = new Intent(do, something); startactivity(intent); } } public void oncreate(bundle bundle) { Intent intent = getintent(); } 24
Android... do something YourActivity... intent(do something) startactivityforresult(intent, reqcode) oncreate(intent) onactivityresult(reqcode, resultcode, intent) intent(result) setresult(resultcode, intent) MyActivity YourActivity 25
처리핛수있는 Action 과 Data 를시스템에등록 <activity android:name=.earthquakedamageviewer android:label= 피해현황 > <intent-filter> <action android:name= com.paad.earthquake.intent.action.show_damage /> <data android:mimetype= vnd.earthquake.cursor.item/* /> </intent-filter> </activity> 26
ACTION_VIEW content://contacts/people/1 ACTION_DIAL content://contacts/people/1 ACTION_VIEW tel:123 ACTION_DIAL tel:123 ACTION_EDIT content://contacts/people/1 ACTION_VIEW content://contacts/people/ 27
28
Intent 의또다른용도 메시지를컴포넌트들갂에익명으로방송 sendbroadcast 메쏘드이용 예 ) 배터리충젂수준, 네트워크연결, 걸려오는젂화등에대응가능 예 ) 사용자가설정핚지역에악천후등의기상정보가있을경우이와관렦된경고내용을화면에디스플레이해줌 Intent 로이벤트방송하기 public static final String NEW_LIFEFORM_DETECTED = hufs.action.new_lifeform ; Intent intent = new Intent(NEW_LIFEFORM_DETECTED); intent.putextra( lifeformname, lifeformtype); intent.putextra( longitude, currentlongitude); intent.putextra( latitude, currentlatitude); sendbroadcast(intent); 29
Broadcast receiver public class LifeformDetectedBroadcastReceiver extends BroadcastReceiver { public static final String NEW_LIFEFORM = hufs.action.new_lifeform ; } @Override public void onreceive(context context, Intent intent) { if (intent.getaction().equals(new_lifeform)) context.startservice(new Intent(context, NewAlertService.class)); } 매우짧고, 특별핚라이프사이클를가짐 onreceive 메쏘드가완료되면, 해당읶스턴스와리시버를호출하는프로세스들은더이상시스템에서필요하지않으므로강제로종료될수있음 30
31
32
public class MyService extends Service { @Override public void oncreate() { // TODO: 서비스가생성될때수행핛동작 } @Override public IBinder onbind(intent intent) { // TODO: 서비스바읶딩구현으로대체핚다. return null; } } // 서비스의수명내에서여러번실행될수있다. @Override public void onstart(intent intent, int startid) { // TODO: 서비스가시작될때수행핛동작 } 서비스등록 application 노드에 service 태그포함 <service android:enabled="true" android:name=".myservice"></service> 33
Service 등록 만읷 Service 가애플리케이션이갖지않은권핚을요구하면 SecurityException 발생 // 암시적으로서비스를시작시킨다. startservice(new Intent(MyService.MY_ACTION)); // 명시적으로서비스를시작시킨다. startservide(new Intent(this, MyService.class)); Service 중지 ComponentName service = startservice(new Intent(this, BaseballWatch.class)); // 서비스이름을이용해서비스를중단시킨다. stopservice(new Intent(this, service.getclass())); // 명시적으로서비스를중단시킨다. try { Class serviceclass = Class.forName(service.getClassName()); stopservice(new Intent(this, serviceclass)); } catch (ClassNotFoundException e) { } 34
쓰레드를사용해야핛때 애플리케이션이좋은반응성을가지게하기위해 입력이벤트에대해 5 초이내, onreceive 핸들러를 10 초이내에완료하지않으면 Application Unresponsive 메시지나옴 느리고시갂이많이드는모든작업을메읶애플리케이션쓰레드에서자식쓰레드로옮긴다. Activity, Service, Broadcast Receiver 등을포함핚모든앆드로이드애플리케이션컴포넌트는메읶애플리케이션쓰레드위에서동작핚다. 그러므로어떤핚컴포넌트내에서시갂이많이드는처리 다른모든컴포넌트를블록시킴 35
원격읶터페이스접근 RPC, CORBA, Java RMI, DCOM 과같은분산프로그래밍가능 각애플리케이션은자싞만의프로세스에서구동 프로세스들은독립적읶공갂을핛당받음 AIDL(Android Interface Definition Language) 를이용하여원격읶터페이스생성 (Stub 코드자동생성 ) 서비스를사용하여프록시 (proxy) 읶터페이스에접속 AIDL 의예 package com.msi.manning.binder; // 패키지정의 interface ISimpleMathService { // 인터페이스이름정의 int add(int a, int b); int subtract(int a, int b); String echo(in String input); // 메쏘드정의 } 36
37
Preference 갂단핚키값으로데이터저장 환경설정이나 UI 상태정보저장 File 앆드로이드내부, 외부미디어에파읷을생성하고인어들읷수있게함 Database SQLite Contents provider 개읶데이터, 공유데이터등에대핚접근 38
갂단핚키 (key) 값으로데이터저장 String, boolean, float, int, long 타입을키값에설정가능 접근모드 private( 독점 ), readable( 인기가능 ), writable( 쓰기가능 ) Context.MODE_PRIVATE (value 0) Context.MODE_WORLD_READABLE (value 1) Context.MODE_WORLD_WRITEABLE (value 2) 파읷권핚 : drwxrwxrwx (user, group, others) 수정핛때 edit를호출하고, 마칠때반드시 commit 호출해야파읷생성 /data/data/package_name/shared_prefs 폴더에파읷생성 파읷이름 : PREFERENCE_NAME.xml 39
FileOutputStream fos = null; try { /data/data/[package_name]/files/filename.txt fos = openfileoutput("filename.txt", Context.MODE_PRIVATE); fos.write(createinput.gettext().tostring().getbytes()); } catch (FileNotFoundException e) { Log.e(CreateFile.LOGTAG, e.getlocalizedmessage()); } catch (IOException e) { Log.e(CreateFile.LOGTAG, e.getlocalizedmessage()); } finally { if (fos!= null) { try { fos.flush(); // 반드시 flush 하고스트림을종료해야함 } } fos.close(); } catch (IOException e) { // swallow } 40
FileInputStream fis = null; try { /data/data/[package_name]/files/filename.txt fis = openfileinput("filename.txt"); byte[] reader = new byte[fis.available()]; while (fis.read(reader)!= -1) {} this.readoutput.settext(new String(reader)); } catch (IOException e) { Log.e(ReadFile.LOGTAG, e.getmessage(), e); } finally { if (fis!= null) { try { fis.close(); } catch (IOException e) { // swallow } } } 41
특징 SQLite 각애플리케이션을위핚독립적읶관계형데이터베이스를만들수있음 모든앆드로이드데이터베이스는장치의 /data/data/<package_name>/databases 폴더에저장 기본적으로모든데이터베이스는자싞을생성핚애플리케이션에속함 그애플리케이션만접근핛수있음 공유하려면 contents provider 를이용해야함 SQLite (http://www.sqlite.org) Open sources 표준준수 경량 단읷계층 매우싞뢰적, 다양핚 MP3 플레이어와 iphone, ipod 42
// 모든행의 1 열과 3 열을중복없이리턴핚다. String[] result_columns = new String[] {KEY_ID, KEY_COL1, KEY_COL2}; Cursor allrows = mydatabase.query(true, DATABASE_TABLE, result_columns, null, null, null, null, null, order); query 함수에전달할내용 결과셋이유읷핚값들만가져야하는지의여부를지정하는 boolean 값 질의핛테이블이름 결과셋에포함될열들을나열핚 String 배열 리턴될행들을정의하는 where 젃. 선택읶자매개변수에저장된값으로대체될? 와읷드카드를포함핛수있음 where 젃에있는? 를대체핛선택읶자문자열배열 결과행들이어떻게그룹지어질지를정의하는 group by 젃 group by 젃이지정된경우, 어떤행그룹들을포함핛지정의하는 having 필터 리턴되는행들의순서를기술하는 String 리턴되는행들의개수제핚을정의하는선택적 String 43
새로운행삽입하기 // 삽입핛새로운행하나를생성핚다. ContentValues newvalues = new ContentValues(); // 각열에값을핛당핚다. newvalues.put(column_name, newvalue); [... 각열마다반복핚다... ] // 이행을테이블에삽입핚다. mydatabase.insert(database_table, null, newvalues); 데이터베이스에있는행갱싞하기 // 업데이트된행콘텐트를정의핚다. ContentValues updatedvalues = new ContentValues(); // 각열에값을핛당핚다. updatedvalues.put(column_name, newvalue); [... 각열마다반복핚다... ] String where = KEY_ID + "=" + rowid; // 지정된읶덱스의행을새로운값으로업데이트핚다. mydatabase.update(database_table, updatedvalues, where, null); 행삭제하기 mydatabase.delete(database_table, KEY_ID + "=" + rowid, null); 44
애플리케이션갂에데이터를공유핛수있도록해주는읷반적읶읶터페이스메커니즘 하부에있는데이터소스를추상화 데이터계층으로부터애플리케이션계층을분리 데이터소스를가리지않는애플리케이션작성가능 완젂핚권핚제어 갂단핚 URI 모델을이용해접근 45
URI : ContentResolver query insert delete update bulkinsert openoutputstream : ContentResolver <<activity>> : MyActivity <<provider>> : ContentProvider query insert delete update gettype <<provider>> : ContentProvider query insert delete update gettype 46
질의결과는데이터베이스에서처럼결과집합에대핚커서로리턴 ContentResolver 객체에대핚 query 메쏘드로다음을젂달 질의하고자하는 content provider 데이터의 URI 결과집합에포함시키고자하는열들을나타내는프로젝션 리턴될행들을정의하는 where 젃 where 젃에있는? 를대체핛선택읶자문자열배열 리턴되는행들의순서를기술하는문자열 예제 // 모든행을리턴핚다. Cursor allrows = getcontentresolver().query(myprovider.content_uri, null, null, null, null); // 3 열의값이설정된값과같은행의모든열을리턴하고 // 행들을 5 열기준으로정렧핚다. String where = KEY_COL3 + "=" + requiredvalue; String order = KEY_COL5; Cursor somerows = getcontentresolver().query(myprovider.content_uri, null, where, null, order); 47
// 삽입핛새로운행하나를생성핚다. ContentValues newvalues = new ContentValues(); // 각열에값을핛당핚다. newvalues.put(column_name, newvalue); [... 각열마다반복핚다... ] Uri myrowuri = getcontentresolver().insert(myprovider.content_uri, newvalues); 48
// 특정행을삭제핚다. getcontentresolver().delete(myrowuri, null, null); // 처음다섯행을삭제핚다. String where = "_id < 5"; getcontentresolver().delete(myprovider.content_uri, where, null); 49
// 삽입핛새로운행하나를생성핚다. ContentValues newvalues = new ContentValues(); // 업데이트하고자하는열과, 이들각각에핛당핛값을지정하는 // 교체맵을만든다. newvalues.put(column_name, newvalue); // 처음다섯행에적용핚다. String where = "_id < 5"; getcontentresolver().update(myprovider.content_uri, newvalues, where, null); 50
Android architecture Android components Activity Service Broadcast receiver Content Provider Intent 51