티스토리 뷰
10. IntentService를 활용하자
액티비티와 프래그먼트 수명주기에 의존하지 않고 백그라운드에서 처리하고 싶은 경우 일반적으로 IntentService가 최적의 선택이 됩니다. 여기서는 백그라운드로 벤치마크에서도 자주 이용되는 피보나치 수열을 계산하고, 그 결과를 LocalBroadcastReceiver를 통해 액티비티에 전달해 봅니다.
이용방법
IntentService 를 이용하는 클래스를 만든다
AndroidManifast.xml에 등록하면 됩니다.
안드로이드 스튜디오에 생성용 메뉴가 있으니깐 그걸 이용하도록 합시다.
그러면 AndroidManifast.xml 에 자동으로 등록 해줍니다.
IntentService.onHandleIntent 는 워커 스레드로 실행되므로 이 안에서 계산을 처리하면 됩니다.
전체 소스
AndroidManifast.xml
FibService.java
: IntentService 클랙스를 상속해서 사용합니다
또한 생성자에 이름을 꼭 넘겨 주도록 해야 합니다.
public FibService() {
super("FibService");
}
/**
* 피보나치 수열을 계산하는 IntentService
*
* onHandleIntent 안은 워커 스레드(메인 스레드가 아닌)에서 실행됩니다
*/
public class FibService extends IntentService {
// 서비스 액션
static final String ACTION_CALC = "ACTION_CALC";
// 브로드 캐스트 액션
static final String ACTION_CALC_DONE = "ACTION_CALC_DONE";
// 브로드캐스트로 계산 결과를 주고 받기 위한 키
static final String KEY_CALC_RESULT = "KEY_CALC_RESULT";
// 브로드캐스트로 계산에 걸린 시간(초)을 주고받기 위한 키
static final String KEY_CALC_MILLISECONDS = "KEY_CALC_MILLISECONDS";
// 피보나치 수열 계산
static final int N = 40;
public FibService() {
super("FibService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_CALC.equals(action)) {
long start = System.nanoTime();
int result = fib(N);
long end = System.nanoTime();
Intent resultIntent = new Intent(ACTION_CALC_DONE);
// 결과값 인텐트 부여
resultIntent.putExtra(KEY_CALC_RESULT, result);
resultIntent.putExtra(KEY_CALC_MILLISECONDS, (end - start) / 1000 / 1000);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(resultIntent);
}
}
}
/**
* 피보나치 수열 계산
*/
private static int fib(int n) {
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
private IntentFilter mIntentFilter;
private LocalBroadcastManager mLocalBroadcastManager;
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("TEST", "getACtion : " + intent.getAction());
String action = intent.getAction();
if (FibService.ACTION_CALC_DONE.equals(action)) {
int result = intent.getIntExtra(FibService.KEY_CALC_RESULT, -1);
long msec = intent.getLongExtra(FibService.KEY_CALC_MILLISECONDS, -2);
// 결과 표시
mTextView.setText("fib(" + FibService.N + ") = " + result + " (" + msec + ")밀리초" );
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(getApplicationContext());
mIntentFilter = new IntentFilter(FibService.ACTION_CALC_DONE);
Intent serviceIntent = new Intent(FibService.ACTION_CALC);
serviceIntent.setClass(getApplication(), FibService.class);
startService(serviceIntent);
mTextView = findViewById(R.id.my_text);
mTextView.setText("계산중 ... ");
}
@Override
protected void onResume() {
super.onResume();
// LocalBroadcastReceiver 받도록 등록
mLocalBroadcastManager.registerReceiver(broadcastReceiver, mIntentFilter);
}
@Override
protected void onPause() {
super.onPause();
// 등록한 LocalBroadcastReceiver 해제
mLocalBroadcastManager.unregisterReceiver(broadcastReceiver);
}
}
IntentService는 HandlerThread. Looper, Handler를 조합해 실용적으로 구현돼 있고,
또한 코드 양도 적으므로 구현 방식을 읽어둘 가치가 있습니다.
'android' 카테고리의 다른 글
12.GitHubService Ex (1) | 2018.07.06 |
---|---|
11.ContentProbider을 알자 (0) | 2018.05.26 |
9. 상주 서비스를 만들자 (0) | 2018.05.23 |
8. Service의 종류와 수명주기를 이해하자 (0) | 2018.05.20 |
7. LocalBroadcastReceiver 를 이해하자 (0) | 2018.05.20 |