Android2014. 8. 21. 12:41


[문제]
InentService를 상속받아서 구현을 했는데, onHandleIntent()가 호출되지 않는 경우가 발생했습니다.

[해결방법]
구글 문서에 따르면, Intent Service를 구현할 때는 생성자와 onHandleIntent()만 구현하면 된다라고 설명하고 있습니다. 다른 콜백 함수들은 구현해도 되고 안해도 되는 것 처럼 적어놨습니다.

That's all you need: a constructor and an implementation of onHandleIntent().

그런데, (저의 경우) onHandleIntent()가 호출되지 않아서 방법을 찾아봤더니, onStartCommand()함수를 구현하면 해결이 되었습니다. (그렇다면 항상 onStartCommand()를 재정의해야 하는 것 아닌가 싶은데 왜 저렇게 적어놨는지는 모르겠습니다.) 

이때, 반드시, 부모 함수(super)를 호출해줘야 하고 반환 값은 반드시 default로 구현된 내용을 유지해줘야 합니다. (즉, 반환값을 임의로 "START_STICKY"를 반환하면 안됩니다.)

If you decide to also override other callback methods, such as onCreate(), onStartCommand(), or onDestroy(), be sure to call the super implementation, so that the IntentService can properly handle the life of the worker thread.

For example, onStartCommand() must return the default implementation (which is how the intent gets delivered to onHandleIntent()):

결과적으로 코드는 아래와 같은 형태가 됩니다. 이제 다른 Activity나 다른 App에서 startService()를 호출하면 onHandleIntent()가 잘 호출됩니다. 당연히 startService()를 호출할 때 넣어준 Intent도 파라메터로 잘 들어옵니다.

public class MyIntentService extends IntentService {
	public static final String PARAM_IN_MSG = "IN_MSG";

	public MyIntentService() {
		super("MyIntentService");
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, flags, startId);
	}
	
	@Override
	protected void onHandleIntent(Intent intent) {
		String msg = intent.getStringExtra(PARAM_IN_MSG);
		String resultTxt = msg + " "+ DateFormat.format("MM/dd/yy h:mmaa", System.currentTimeMillis());
		Toast.makeText(this, "onHandleIntent Called : " + resultTxt, Toast.LENGTH_LONG).show();
	}
}




[원문보기]


[추가1]
아무래도 뭔가 이상해서, IntentService의 코드를 찾아봤습니다.
코드에서는 onStartCommand()에서 onStart()를 호출. onStart()에서는 핸들러에 메시지를 던지고 결국 onHandleIntent()를 호출하고 있습니다. 코드에는 문제가 없어보이는데, 왜 상속받아 만든 클래스에서 onStartCommand()를 재정의해야만 onHandleIntent()가 호출되는 걸까요? 혹시, 아시는 분 계시면 한 수 가르쳐주세요 ^^

private final class ServiceHandler extends Handler {
	public ServiceHandler(Looper looper) {
		super(looper);
	}
	@Override
	public void handleMessage(Message msg) {
		onHandleIntent((Intent) msg.obj);
	}
}
@Override
public void onStart(Intent intent, int startId) {
	Message msg = mServiceHandler.obtainMessage();
	msg.arg1 = startId;
	msg.obj = intent;
	mServiceHandler.sendMessage(msg);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
	onStart(intent, startId);
	return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}







Posted by 데브로망스