본문 바로가기

IT

Service stopService() 시 onDestroy() 가 작동하지 않거나 원하는 타이밍에 작동하지 않는 경우

반응형

 하드웨어 제어 서비스를 프로그래밍하면서 잘 작동하던 Service의 onDestroy() 메소드가 stopService() 실행에 바로 작동하지 않는 경우가 있어서 이를 남겨본다.


 생명주기상 안드로이드의 Service는 startService 또는 bindingService로 Service를 시작할 수 있는데 이중에 bindingService시 flag를 어떤 것을 사용하는지 어디서 startService가 발현하는지에 따라서 다양한 경우가 발생했다.


 이중에서 내 프로그램에서 원하는대로 (stopService실행시 onDestroy를 바로타는 것) 처리할 수 있는 것은 bindingService에서 사용하는 flag를 변경하여 원하는 결과를 얻었다.


// java code
private void bindingCradle() {
	DLog.d(TAG, "bindingCradle()");
	// 크레들과 바인딩
	conn = new CradleServiceConnection();
	startService(new Intent(BusinessActivity.this, CradleService.class));
	bindService(new Intent(BusinessActivity.this, CradleService.class), 
			conn, Context.BIND_AUTO_CREATE);
}

문제가 된 부분은 'Context.BIND_AUTO_CREATE' 이 flag이다. 이를 Context.BIND_ADJUST_WITH_ACTIVITY 으로 변경한 것만으로 정상적으로 원하는 타이밍에 onDestroy() 가 정상적으로 작동하였다.


// java code
private void bindingCradle() {
	DLog.d(TAG, "bindingCradle()");
	// 크레들과 바인딩
	conn = new CradleServiceConnection();
	startService(new Intent(BusinessActivity.this, CradleService.class));
	bindService(new Intent(BusinessActivity.this, CradleService.class), 
			conn, Context.BIND_ADJUST_WITH_ACTIVITY);
}

요렇게 말이다. 아래는 안드로이드 doc에서 발췌한 부분이다.


http://developer.android.com/reference/android/content/Context.html#BIND_ABOVE_CLIENT

public static final int BIND_ABOVE_CLIENT

Added in API level 14

Flag for bindService(Intent, ServiceConnection, int): indicates that the client application binding to this service considers the service to be more important than the app itself. When set, the platform will try to have the out of memory killer kill the app before it kills the service it is bound to, though this is not guaranteed to be the case.

Constant Value: 8 (0x00000008)

public static final int BIND_ADJUST_WITH_ACTIVITY

Added in API level 14

Flag for bindService(Intent, ServiceConnection, int): If binding from an activity, allow the target service's process importance to be raised based on whether the activity is visible to the user, regardless whether another flag is used to reduce the amount that the client process's overall importance is used to impact it.

Constant Value: 128 (0x00000080)

public static final int BIND_ALLOW_OOM_MANAGEMENT

Added in API level 14

Flag for bindService(Intent, ServiceConnection, int): allow the process hosting the bound service to go through its normal memory management. It will be treated more like a running service, allowing the system to (temporarily) expunge the process if low on memory or for some other whim it may have, and being more aggressive about making it a candidate to be killed (and restarted) if running for a long time.

Constant Value: 16 (0x00000010)

public static final int BIND_AUTO_CREATE

Added in API level 1

Flag for bindService(Intent, ServiceConnection, int): automatically create the service as long as the binding exists. Note that while this will create the service, its onStartCommand(Intent, int, int) method will still only be called due to an explicit call to startService(Intent). Even without that, though, this still provides you with access to the service object while the service is created.

Note that prior to ICE_CREAM_SANDWICH, not supplying this flag would also impact how important the system consider's the target service's process to be. When set, the only way for it to be raised was by binding from a service in which case it will only be important when that activity is in the foreground. Now to achieve this behavior you must explicitly supply the new flag BIND_ADJUST_WITH_ACTIVITY. For compatibility, old applications that don't specify BIND_AUTO_CREATE will automatically have the flags BIND_WAIVE_PRIORITY and BIND_ADJUST_WITH_ACTIVITY set for them in order to achieve the same result.

Constant Value: 1 (0x00000001)

public static final int BIND_DEBUG_UNBIND

Added in API level 1

Flag for bindService(Intent, ServiceConnection, int): include debugging help for mismatched calls to unbind. When this flag is set, the callstack of the following unbindService(ServiceConnection) call is retained, to be printed if a later incorrect unbind call is made. Note that doing this requires retaining information about the binding that was made for the lifetime of the app, resulting in a leak -- this should only be used for debugging.

Constant Value: 2 (0x00000002)

public static final int BIND_IMPORTANT

Added in API level 14

Flag for bindService(Intent, ServiceConnection, int): this service is very important to the client, so should be brought to the foreground process level when the client is. Normally a process can only be raised to the visibility level by a client, even if that client is in the foreground.

Constant Value: 64 (0x00000040)

public static final int BIND_NOT_FOREGROUND

Added in API level 8

Flag for bindService(Intent, ServiceConnection, int): don't allow this binding to raise the target service's process to the foreground scheduling priority. It will still be raised to at least the same memory priority as the client (so that its process will not be killable in any situation where the client is not killable), but for CPU scheduling purposes it may be left in the background. This only has an impact in the situation where the binding client is a foreground process and the target service is in a background process.

Constant Value: 4 (0x00000004)

public static final int BIND_WAIVE_PRIORITY

Added in API level 14

Flag for bindService(Intent, ServiceConnection, int): don't impact the scheduling or memory management priority of the target service's hosting process. Allows the service's process to be managed on the background LRU list just like a regular application process in the background.

Constant Value: 32 (0x00000020)


반응형