본문 바로가기
Android 기법/# Study

[Android]IntentService와 BroadcastReceiver를 통해 Background Thread로 처리하기

by 퍼즐잎 2017. 7. 23.



이번에 IntentService를 이용해 Background Thread에서 작업을 수행해봤습니다.

샘플 예제에서는 SQLite로 약간의 DB 작업을 하고, 구글 맵을 이용해 위도 경도를 구하고

이것을 이용해 Geocoder로 주소값을 구합니다.



[샘플 예제]

https://github.com/PuzzleLeaf/Android-MiniProject3



DB작업에서는 데이터가 몇 개 없어서 괜찮은데

Geocoder에서는 Main Thread에서 작업하면 약간의 멈춤 현상이 발생합니다.





그래서 이러한 작업들을 처리하는 IntentService를 상속한 클래스를 생성합니다.



1
2
3
4
5
6
7
8
9
10
11
12
public class DbService extends IntentService {
 
    public DbService() {
        super("DbService");
    }
 
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
       //수행할 작업들
    }
}
 
cs


onHandleIntent 메소드에 Background Thread를 통해서 수행할 작업들을 입력해 줍니다.

IntentService에 여러 작업명령이 들어오면 Queue 처럼 작업 목록들이 쌓이게 되고 순서대로 처리가 됩니다.

Service를 사용하기 위해서 Manifest에서 아래와 같이 추가해 주고


1
        <service android:name=".service.DbService"/>
cs




DbService에 DB에서 처리할 작업들을 써 주고 이것을 사용하기 위해서는 startService로 호출해 줘야 합니다.



1
2
3
                Intent intent = new Intent(this, DbService.class);
                intent.setAction("서비스 작업들을 구분하기 위한 인자");
                startService(intent);
cs


DB 작업을 수행할 곳에 다음과 같이 Intent를 지정하고

startService로 Background Thread로 작업을 처리하라 명령을 내릴 수 있습니다.


이때 여기에서 setAction이 사용되었는데 아까 만들었던 

DbService에서 작업 내용들을 구분할 때 사용할 수 있습니다.


위에 코드에서 조금 추가하면


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class DbService extends IntentService {
 
    public DbService() {
        super("DbService");
    }
 
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
 
        if(intent.getAction().equals("삽입 작업을 수행하는 액션이 넘어왔다")) {
           //작업을 수행한다.
        }
        else if(intent.getAction().equals("갱신 작업을 수행하는 액션이 넘어왔다")){
            //작업을 수행한다.
        }
     
}
 
cs



getAction으로 setAction으로 넘겨준 값과 같으면 그 작업을 수행할 수 있게 구분할 수 있습니다.

그런데 여기에서 작업을 다 수행했으면 MainThread에 어떻게 알려줄 수 있을까요 ? 


여기에서 UI를 변경하던가 ... 등등 작업을 수행하면 앱이 바로 터지게 됩니다...


그래서 BroadcastReceiver를 이용해서 작업이 끝났음을 인식할 수 있게 구현했습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class DbService extends IntentService {
 
    public DbService() {
        super("DbService");
    }
 
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
 
        if(intent.getAction().equals("삽입 작업을 수행하는 액션이 넘어왔다")) {
           //작업을 수행한다.
            sendBroadcast(new Intent("삽입 작업 끝났다"));
        }
        else if(intent.getAction().equals("갱신 작업을 수행하는 액션이 넘어왔다")){
            //작업을 수행한다.
            sendBroadcast(new Intent("갱신 작업 끝났다"));
        }
     
}
 
cs



sendBroadcast로 어떤 작업이 끝났다고 알려 줄 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    private DbRefreshBroadCastReceiver dbRefresh = new DbRefreshBroadCastReceiver();
    ...
 
    registerReceiver(dbRefresh, filter);
 
    ...
 
    unregisterReceiver(dbRefresh);
 
    ...
 
     private class DbRefreshBroadCastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("갱신 작업 끝났다")) {
                //작업 수행
            }
            //마커 클릭시 DB 정보 읽어오기 위함
            else if(intent.getAction().equals("삽입 작업 끝났다")){
               //작업 수행
            }
           
        }
    }
cs


이런식으로 BroadcastReceiver를 상속받는 클래스를 생성해서

IntentService에서 넘겨주는 값을 구분하여 어떤 작업을 수행할지 작성하면 됩니다.


그 전에 Broadcast를 받을 수 있게 registerReceiver로 동적으로 등록해야 합니다.

현재 액티비티를 벗어나서 사용하지 않는다면 unregisterReceiver로 해제 하면 됩니다.






댓글