REF_ https://fullstatck.tistory.com/23
· Service : UI없이 실행될 수 있지만 매우 길지 않아야 한다. 만약 오래걸리는 작업을 Service에서 실행하고자 한다면 Service 안에서 스레드를 사용해야 한다.
· IntentService : 오래걸리지만 메인스레드와 관련이 없는 작업을할 때 주로 이용한다. 만약 메인 스레드와 관련된 작업을 해야 한다면 메인스레드 Handler나 Boradcast intent를 이용해야 한다.
· Service : 백드라운드에서 동작하지만 메인스레드에 포함된다.
· IntentService : 새로운 스레드에서 동작한다.
단점?
· Service : 메인스레드에 포함되므로 무거운 작업일때 메인스레드에 영향을주어 느려지거나 할 수 있다.
· IntentService : 병렬적으로 수행될 수 없으므로 연속적인 Intent 호출에 관해서 순차적으로 처리된다.
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(
getApplicationContext(),//현재제어권자
MyService.class); // 이동할 컴포넌트
startService(intent); // 서비스 시작
Log.d("LOGLOG", isMyServiceRunning(MyService.class) + "");
}
}); //시작
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(
getApplicationContext(),//현재제어권자
MyService.class); // 이동할 컴포넌트
stopService(intent); // 서비스 종료
Log.d("LOGLOG", isMyServiceRunning(MyService.class) + "");
}
}); //종료
public boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
} // (if service is running) ? true : false
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("LOGLOG", "Start");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("LOGLOG", "DEAD");
}}
정말 많은 일만 안 하면 꺼질 일 없음
무한루프 돌리니까 어느정도 돌다가 꺼짐
---
Service Binding
startService() 를 통해 서비스가 시작되고 이러한 서비스는 한번 시작되면 백그라운드에서 무한정 실행될수 있습니다. 심지어 서비스를 시작한 액티비티가 소멸되어도 마찬가지 입니다. 그러나 이렇게 시작한 서비스는 호출한 쪽에 어떠한 결과를 반환할수 없습니다. 이를 Unbound Service 라고도 한다
서비스바인딩 이란
startService() 메소드 대신 bindService() 메소드를 통해 시작되는 서비스를 서비스 바인딩 (Service Bind 혹은 Bound Service) 라 한다.
- 이 서비스는 마치 클라이언트-서버 와 같이 동작합니다. 서비스가 서버 역할을 한다.
- 액티비티는 서비스에 어떠한 요청을 할수 있고, 서비스로부터 어떠한 결과를 받을수 있다.
- 프로세스간 통신에도 사용된다.
- 서비스 바인딩은 연결된 액티비티가 사라지면 서비스도 소멸된다. (즉 백그라운드에서 무한히 실행되진 않습니다)
- 하나의 서비스에 다수의 액티비티 연결 가능하다.
- 애플리케이션 안의 기능을 외부에 제공하는 경우에 많이 사용한다.
서비스바인딩 구현 & 동작
- 서비스 바인딩 객체를 생성하려면 콜백 메소드인 onBind() 를 구현해야 한다.
- onBind() 는 IBinder 를 반환하는데, 바로 이 객체가 '서비스'와 '클라이언터' 사이의 인터페이스 역할을 한다.
- 클라이언트가 bindService() 를 호출하면, 클라이언트가 서비스에 연결되면서 IBinder가 반환되고, 클라이언트가 IBinder를 받으면 이 인터페이스를 통해 주고 받는 것이 가능해진다.
- 서비스가 제공하는 다른 메소드 호출 가능.
- 여러 클라이언트가 하나의 서비스에 동시 접속이 가능하며
- 클라이언트가 서비스와의 접속을 마치려면 unbindService() 를 호출한다.
- 서비스에 연결된 클라이언트가 하나도 남아있지 않으면 서비스를 소멸시킨다.
구금에서 검색해보면
Unbound Service 와 Bound Service 의 동작돤계에 해한 흐름도가 다음과 같다.
public class MyService extends Service {
// 외부로 데이터를 전달하려면 바인더 사용
// Binder 객체는 IBinder 인터페이스 상속구현 객체입니다
//public class Binder extends Object implements IBinder
IBinder mBinder = new MyBinder();
class MyBinder extends Binder {
MyService getService() { // 서비스 객체를 리턴
return MyService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
// 액티비티에서 bindService() 를 실행하면 호출됨
// 리턴한 IBinder 객체는 서비스와 클라이언트 사이의 인터페이스 정의한다
return mBinder; // 서비스 객체를 리턴
}
int getRan() { // 임의 랜덤값을 리턴하는 메서드
return new Random().nextInt();
}
@Override
public void onCreate() {
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
Intent intent = new Intent(this, HelloService.class);
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",10);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
Log.d("TEST", String.valueOf(onUnbind(intent)));
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
Log.d("TEST", String.valueOf(startId));
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}