백그라운드 데몬: 배경에서 계속 실행되는 프로세스이다. 클라이언트가 가동시켜 놓기만 하면 사용자의 명령이 없이도 지속적으로 실행된다. MP3 플레이어가 대표적인 예이다. 바운드 서비스: 클라이언트를 위해 특정한 기능을 제공하는 역할을 한다. 자신의 기능을 메서드로 노출시키며 클라이언트는 메서드를 호출함으로써 서비스를 이용한다. 다른 운영체제의 COM, CORBAR에 대응되는 개념이다. 두 개의 서로다른 서비스는 백그라운드에서 동작하며 뉴스 데이터를 출력하는 예제 매니페스트 등록 내용 주요 착안점 서비스의 시작과 종료 방법 호출은 중첩되지 않으므로 몇 번을 시작했건 간에 stopService를 한 번만 호출해도 즉시 종료된다. 서비스는 유일한 이름이 있으므로 외부 패키지나 외부 프로그램에서도 호출 가능하다. 외부에서 다른 패키지에 속한 클래스를 직접 참조할 수 없으므로 이름을 사용하여 다음과 같이 호출한다. 비동기적으로 기능을 해결해주는 컴포넌트이다. 요약 Bind service는 특정 기능을 제공하는 메서드를 클라이언트에게 노출한다. 연산을 처리하는 부분 클라이언트에서 서비스에 연결하거나 해제할 때 다음 메서드를 호출하여 바인딩한다. 바인딩이란 클라이언트와 서비스를 연결하는 동작이다. 마지막 인수 flag는 서비스 바인딩 바익을 지정하는데 통상 아주 복잡한 기능들을 공통으로 서비스에 작성해두고 이것을 원격으로 콜하는 방식으로 구현할 수 있다. 서비스는 로컬에서뿐만 아니라 원격으로도 호출할 수 있는데 그렇게 하려면 자신의 메서드 목록을 인터페이스로 정의해야 한다. 따라서 전달할 수 있는 인수의 타입은 자바기본 타입이나 자바 수준에서 인터페이스를 직접 정의하기는 대단히 어려워 원격 인터페이스를 정의하는 위와 같이 인터페이스안에 노출할 메서드의 선언문만 작성해 두면 AIDL 컴파일러가 이 인터페이스를 구현하는 자바 파일을 생성해 준다. 예전에 구현했던 내용Service
Life Cycle
에서 차이가 존재 한다.백그라운드 데몬 형태 예제
public class NewsService extends Service {
boolean mQuit;
public void onCreate() {
super.onCreate();
}
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service End", Toast.LENGTH_SHORT).show();
mQuit = true;
}
public int onStartCommand (Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
mQuit = false;
NewsThread thread = new NewsThread(this, mHandler);
thread.start();
return START_STICKY;
}
public IBinder onBind(Intent intent) {
return null;
}
class NewsThread extends Thread {
NewsService mParent;
Handler mHandler;
String[] arNews = {
"일본, 독도는 한국땅으로 인정",
"번데기 맛 쵸코파이 출시",
"춘천 지역에 초거대 유전 발견",
"한국 월드컵 결승 진출",
"국민 소득 6만불 돌파",
"학교 폭력 완전 근절된 것으로 조사",
"안드로이드 점유율 아이폰을 앞질렀다",
};
public NewsThread(NewsService parent, Handler handler) {
mParent = parent;
mHandler = handler;
}
public void run() {
for (int idx = 0;mQuit == false;idx++) {
Message msg = new Message();
msg.what = 0;
msg.obj = arNews[idx % arNews.length];
mHandler.sendMessage(msg);
try { Thread.sleep(5000);} catch (Exception e) { ; }
}
}
}
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0) {
String news = (String)msg.obj;
Toast.makeText(NewsService.this, news, Toast.LENGTH_SHORT).show();
}
}
};
}
<service android:name=".c30_service.NewsService" android:enabled="true">
<intent-filter>
<action android:name="andexam.ver6.NEWS" />
</intent-filter>
</service>
handler
를 이용해서 UI를 업데이트함onBind
는 null을 리턴한다.
같은 패키지에 있는 서비스의 경우 서비스 클래스명으로 지정하는 것이 가장 간편하다.
itent = new Intent(“packageName.className”);
startService(intent);
하지만 5.0 이후로는 보안상 문제가 있어서 금지 되었다. Service intent must be explicit
예외가 발생된다.IntentService
startService(Intent)
로 요청하면 작업 스레드를 생성해서 해당 작업을 실행시켜 준다.work queue processor
패턴으로 일반적으로 이용되는 것이 IntentService
이다.
즉, main thread에서 수행해야할 작업을 쉽게 offloading 하는 역할을 한다.public class NewsService2 extends IntentService {
public NewsService2() {
super("NewsThread");
}
protected void onHandleIntent(Intent intent) {
String[] arNews = {
"4T SSD 10만원대 진입",
"갤럭시 S8 판매 호조",
"핵융합 발전소 건설 완료",
};
for (int idx = 0;idx < arNews.length;idx++) {
Message msg = new Message();
msg.what = 0;
msg.obj = arNews[idx % arNews.length];
mHandler.sendMessage(msg);
try { Thread.sleep(5000);} catch (Exception e) { ; }
}
}
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0) {
String news = (String)msg.obj;
Toast.makeText(NewsService2.this, news, Toast.LENGTH_SHORT).show();
}
}
};
}
Bind Service
클라이언트는 서비스에 연결하여 메서드를 호출함으로써 통신을 수행하며 자신이 직접 구현하지 않은 기능을 사용한다.public class CalcService extends Service {
public class CalcBinder extends Binder {
CalcService getService() { return CalcService.this; }
}
CalcBinder mBinder = new CalcBinder();
public IBinder onBind(Intent intent) {
return mBinder;
}
public int getLCM(int a, int b) throws RemoteException {
int i;
for (i = 1; ;i++) {
if (i % a == 0 && i % b == 0) break;
}
return i;
}
public boolean isPrime(int n) throws RemoteException {
int i;
for (i = 2;i < n; i++) {
if (n % i == 0) return false;
}
return true;
}
}
onBind
를 호출하는 부분public class CalcClient extends Activity {
CalcService mCalc;
TextView mResult;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calcclient);
mResult = (TextView)findViewById(R.id.result);
}
public void mOnClick(View v) {
switch (v.getId()) {
case R.id.btnLCM:
int LCM = 0;
try {
LCM = mCalc.getLCM(6, 8);
} catch (RemoteException e) {
e.printStackTrace();
}
mResult.setText("6과 8의 최소 공배수 = " + LCM);
break;
case R.id.btnPrime:
boolean prime = false;
try {
prime = mCalc.isPrime(7);
} catch (RemoteException e) {
e.printStackTrace();
}
mResult.setText("7의 소수 여부 = " + prime);
break;
}
}
public void onResume() {
super.onResume();
Intent intent = new Intent(this, CalcService.class);
bindService(intent, srvConn, BIND_AUTO_CREATE);
}
public void onPause() {
super.onPause();
unbindService(srvConn);
}
ServiceConnection srvConn = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
mCalc = ((CalcService.CalcBinder)binder).getService();
}
public void onServiceDisconnected(ComponentName className) {
mCalc = null;
}
};
}
bindService
의 첫 번째 인수는 같은 패키지에 있으면 클래스명으로 지정하고 외부에 있다면 서비스의 액션명을 사용한다.
두 번째 인수 conn
은 서비스가 연결, 해제될 때의 동작을 정의하는 연결 객체이다.
서비스를 사용하는 클라이언트는 ServiceConnection
인터페이스를 구현하는데 클라이언트와 서비스가 연결되거나 해제될 때 호출되는 콜백 메서드
를 정의한다. 아래의 코드가 이에 해당한다. ServiceConnection srvConn = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
mCalc = ((CalcService.CalcBinder)binder).getService();
}
public void onServiceDisconnected(ComponentName className) {
mCalc = null;
}
};
onResume()
에서 bindService(intent,srvConn,BIND_AUTO_CREATE)
를 하기 때문에 해당 callback method를 구현해야 한다.
만약 그냥 별도의 anonymous class 생성 없이 activity에 구현 했다고 하면 this
가 된다.BIND_AUTO_CREATE
로 지정하여 서비스를 자동으로 가동시킨다.완전 원격 서비스
이는 단순히 메서드의 원형을 선언하는 것과 수준이 다른데 원격에서 호출되는 메서드는 응용 프로그램의 경계를 넘어서 인수를 전달해야 하는 어려움이 있다. 각 응용프로그램이 사용하는 메모리가 완전히 분리되어 있어 통상의 방법으로는 인수를 넘기기 어렵다.Parcelable
정도로 제한되며 그 외에도 몇 가지 제약이 존재한다.AIDL
이라는 별도의 언어를 제공한다.interface A{
int getLCM();
boolean isPrime();
}
네이버 블로그 포스트
'Computer Science > Android Application' 카테고리의 다른 글
Preference (0) | 2017.08.20 |
---|---|
Broadcast Receiver (0) | 2017.08.16 |
Activity (0) | 2017.08.16 |
쓰레드 (Thread) (0) | 2017.08.04 |
이벤트 (Event) (0) | 2017.08.04 |