activity 와 service
안드로이드 4대 구성요소중 둘. activity 는 UI 즉 메인쓰레드 상의 모든 action 을 의미하고
service 는 백그라운드에서 주로 돌아간다.
activity 는 oncreate - onstart - onresume - onpause - onstop - ondestroy 순서로 진행되며 끝 2개씩을 쌍으로 생각할 수 있다. 또, 자식 activity 를 실행하기 위해선 StartActivityForResult 를 쓰고, 자식 activitiy 에서 무언가를 받아야 한다며 OnActivityResult 를 사용한다.
생명주기에 대한 자세한 내용, activity 의 선언, activity 의 이동에 대해선 다음 포스팅을 참고하면 좋다
https://yeon-lee.tistory.com/126
service 는 oncreate, ondestroy 를 공유하고, startservice, bindservice 두가지 실행 시나리오가 있으며 startservice 는 onstartcommand 로 실행이 되고 독립적으로 실행되는 반면 bindservice 는 onbind 로 구성요소에 bind 되어 생명주기를 함께한다.
더 자세한 서비스에 대한 내용은 다음 포스팅을 참고하면 좋다
https://yeon-lee.tistory.com/128
aidl
https://kjwsx23.tistory.com/187
activity 에서 socket 통신을 해야한다. service 에서 bind, listen, connect 등을 진행하고 해당 결과를 activity 로 받아야 해서 위 링크를 참고해서 만들었다.
aidl 양방향 : https://yeon-lee.tistory.com/193 aidl 통신 : https://yeon-lee.tistory.com/194 https://yeon-lee.tistory.com/189 aidl 구조 : https://yeon-lee.tistory.com/137 https://yeon-lee.tistory.com/127 https://yeon-lee.tistory.com/125
socketmanager 라는 객체를 application 을 상속받아서 singleton 으로 구현하였다. activity 가 통신할 때 동일한 소켓만을 사용하게 하고, 어떤 activity 에서도 접근해서 사용할 수 있게 하기 위함이다. 또, 앱의 모든 생명주기 상에 존재하기에 background 작업을 하는 service 와 함께 사용하기에 적절했다.
public class SocketManager extends Application {
private static final SocketManager instance = new SocketManager();
...
실제 socket connect 를 담당할 connectionService 에는 interface.stub 대로 구현한 binder 객체를 정의를 다음과 같이 합니다.
IConnectionService.Stub binder = new IConnectionService.Stub() {
@Override
public int getStatus() throws RemoteException {
return status;
}
@Override
public void setSocket(String ip) throws RemoteException {
mySetSocket(ip);
}
@Override
public void connect() throws RemoteException {
myConnect();
}
@Override
public void disconnect() throws RemoteException {
myDisconnect();
}
@Override
public void send() throws RemoteException {
mySend();
}
@Override
public void receive() throws RemoteException {
myReceive();
}
};
service에서 정의한 이 binder 를 socketManager 에서 사용함으로써 activity 에서 소켓 통신을 할 수 있도록 구현하였습니다.
cgMsg = manager.getCG(sendCGMsg.msgId, i++);
보면 get 하는 부분을 loop 를 사용해서 msgID, msgSubID 형식으로 받고 있는데 이는 대용량 파일을 효과적으로 처리하기 위해서 이중 해쉬맵을 이용했다. 큰 파일을 <msgID, <msgSubId, JSON>> 형식으로 담았고 이를 순차적으로 꺼내는 구조를 가진다.
static HashMap<Integer, HashMap<Integer, JSONObject>> cgMsgMap = new HashMap<>();
void pushCGMsgToMap(JSONObject obj) {
try {
int msgId = obj.getInt("msg_id");
synchronized (cgMsgMap) {
HashMap<Integer, JSONObject> subMsgMap;
subMsgMap = cgMsgMap.get(msgId);
if (subMsgMap != null) {
subMsgMap.put(obj.getInt("msg_sub_id"), obj);
} else {
subMsgMap = new HashMap<>();
subMsgMap.put(obj.getInt("msg_sub_id"), obj);
cgMsgMap.put(msgId, subMsgMap);
}
cgMsgMap.notify();
}
} catch (JSONException e) { }
}
'개발 > Android Studio' 카테고리의 다른 글
[Android] aidl 로 양방향 통신하기 (0) | 2023.04.12 |
---|---|
[Android] [통신#1] activity 간 intent 로 통신하기 (0) | 2023.04.10 |
[Android] Aidl 로 class 옮기기 (0) | 2023.04.04 |
[Android] PackageManager (0) | 2023.03.25 |
[Android] activity 를 intent 로 실행하는법 (startActivity startActivityForResult) (0) | 2023.03.24 |