일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 안드로이드
- 안드로이드 sunflower
- 막내의막무가내 SQL
- 막내의막무가내 안드로이드 에러 해결
- Fragment
- 막내의 막무가내
- flutter network call
- 부스트코스
- 막내의막무가내 코볼 COBOL
- 막내의막무가내 안드로이드
- 막내의막무가내 일상
- 막내의막무가내 플러터 flutter
- 막내의막무가내 플러터
- 부스트코스에이스
- 막내의막무가내 목표 및 회고
- 주택가 잠실새내
- 막내의막무가내 코틀린
- 막내의막무가내 안드로이드 코틀린
- 주엽역 생활맥주
- 막내의막무가내
- 막내의막무가내 코틀린 안드로이드
- 막무가내
- 막내의막무가내 rxjava
- 막내의막무가내 프로그래밍
- 막내의막무가내 알고리즘
- 프래그먼트
- 프로그래머스 알고리즘
- 막내의 막무가내 알고리즘
- 2022년 6월 일상
- 안드로이드 Sunflower 스터디
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[안드로이드] otto 라이브러리 ( An event bus by Square ) 본문
square사에서 만든 otto(오투) 라이브러리에 대해 포스팅을 해보겠습니다.
https://github.com/square/otto
참고 : https://gun0912.tistory.com/4
이 라이브러리는 bundle과 intent putExtra와도 조금 비슷하다고 처음에는 느꼈으나 이것을 더 강화시킨 라이브러리 같다는 생각이 들었습니다. 그리고 다른 액티비티에 있는 값들을 static으로 선언한것처럼 다른 액티비티의 원하는 값을 갖고 오는 듯한 효과를 가질 수 있습니다.
오토는 이벤트버스라고도 불립니다. 이벤트 버스라는 이름처럼 하는역할이 마치 버스와 비슷합니다. 제가 이해한대로 쉽게 설명하자면, 버스에 다른 액티비티 또는 프래그먼트에 전달할 데이터를 넣습니다. 그리고 버스는 이 데이터를 싣고 정류장마다(액티비티) 멈춥니다. 여기서 정류장은 액티비티마다 하나씩 존재할 수 있는데 액티비티에서 정류장을 설치해놀수도 있고 안해놓을 수도 있습니다. 즉 정류장을 설치해논 액티비티에만 데이터를 싣은 버스가 도착해서 그들이 원하는 데이터가 있으면 주게됩니다.
쉽게 설명하면 위와 같고 조금 더 정확히(?) 설명하면 이벤트를 감지하고자하는 액티비티 혹은 프래그먼트가 있고 이벤트가 발생하면 이벤트버스는 이벤트를 감지하는 액티비티 혹은 프래그먼트들에게 이벤트를 전달해줍니다. 그럼 받는쪽은 자신이 감지하고 있던 이벤트가 맞으면 데이터를 가져올 수 있습니다... 다른 분의 블로그나 공식문서 참고하시는게 정확하게 이해하는데는 더좋을 것 같습니다. ㅎㅎㅎ
저같은 경우는 어댑터에서 액티비티쪽으로 데이터를 전달하는 경우만 써보았습니다.
이제 사용법에 대해 정리해보겠습니다. (제가 사용한 예제에서 가져오겠습니다.)
1. gradle에 다음을 추가합니다.
implementation 'com.squareup:otto:1.3.8'
2. 먼저 가장중요한 버스 클래스부터 만들어보겠습니다. 다음과 같이 싱글톤 형식으로 생성합니다. BusProvider라는 이름으로 만들었습니다.
import com.squareup.otto.Bus;
import com.squareup.otto.ThreadEnforcer;
public class BusProvider {
public static final Bus bus = new Bus(ThreadEnforcer.ANY);
public static Bus getInstance(){
return bus;
}
public BusProvider() {
}
}
3. 처음 말할때 이벤트버스라고 했습니다. 이벤트 즉 데이터를 버스에 싣고 버스가 정류장을 한바퀴 도는것입니다.
그렇다면 제가 전달할 객체를 다음과 같이 정의해보록 하겠습니다. 객체도 전달 할 수 있으므로 전 객체로 정의해봤습니다.
public class HeartEvent {
String id;
boolean like;
public HeartEvent(String id, boolean like) {
this.id = id;
this.like = like;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public boolean isLike() {
return like;
}
public void setLike(boolean like) {
this.like = like;
}
}
4. 버스에 데이터를 넣어줍니다. 앞서 선언해논 HearEvent객체에 데이터를 저장해 버스에 실고 버스를 출발시켜보겠습니다.(이벤트버스 출발) BusProvider.getInstance().post(데이터); 이런식으로 해줍니다. 코드는 다음과 같습니다.
heartBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MiniGram miniGram = miniGramArrayList.get(getAdapterPosition());
if(miniGram.getLike()){
miniGram.setLike(false);
HeartEvent heartEvent = new HeartEvent(miniGram.getId(), false);
BusProvider.getInstance().post(heartEvent);
}else{
miniGram.setLike(true);
HeartEvent heartEvent = new HeartEvent(miniGram.getId(), true);
BusProvider.getInstance().post(heartEvent);
}
}
});
4. 이제 이 버스가 자기가 정류장을 설치한 액티비티 혹은 프래그먼트에 도착할 수 있도록 3번과 다른 액티비티에 정류장을 설치해보겠습니다.
4-1) 전역 변수로 Bus bus = BusProvider.getInstance(); 를 생성해줍니다.
4-2) onCreate() 안의 setContentView밑에 bus.register(this); 로 정류장을 등록해줍니다.
4-3) @Subscribe 어노테이션을 적어주고 이벤트버스에서 보낸 이벤트를 받을 수 있게 해줍니다. 저는 내부에 레트로핏통신을 하는 코드가 적혀있는데 그냥 매개변수로 HeartEvent에 보내준 데이터를 가져올 수 있다고 생각하시면 될 것 같습니다. 즉 이벤트가 발생한 뒤 정류장에 해당 이벤트가 도착하면 수행할 함수입니다.
@Subscribe //이벤트버스에서 보낸 이벤트가 여기에 정착을 하는 정류소를 만든다고 생각
public void updateLike(HeartEvent heartEvent) {//public항상 붙여줘야함
miniGramService.updateLike(heartEvent.getId(), heartEvent.isLike()).enqueue(new Callback<MiniGram>() {
@Override
public void onResponse(Call<MiniGram> call, Response<MiniGram> response) {
if(response.isSuccessful()){
Log.d("like update", "sucess");
}else{
Log.d("like update", "failed");
}
}
@Override
public void onFailure(Call<MiniGram> call, Throwable t) {
Log.d("like update", "not connected");
}
});
}
5. 마지막으로 이 액티비티가 생명주기가 끝나거나 필요없는 시점에는 이벤트버스가 쓸데없이 해당 액티비티 정류장에 들어올 필요가 없습니다. 그러므로 등록한 정류장을 해제해주도록 합니다. 저는 finish()에 오버라이딩하여 구현을 했으나 해제시점은 원하는데에 하시면 됩니다. onDestory()에 해도 됩니다.
@Override
public void finish() {
super.finish();
bus.unregister(this); //이액티비티 떠나면 정류소 해제해줌
}
이벤트를 감지하는(정류소등록을한) 액티비티 전체코드와 함께 이상 포스팅을 마치겠습니다. 감사합니다
package com.mtjinse.myminiinstgram;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import com.mtjinse.myminiinstgram.models.MiniGram;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
public static final String BASE_URL = "http://memolease.ipdisk.co.kr:1337";
Retrofit retrofit;
MiniGramService miniGramService;
RecyclerView minigram_recycler;
MiniGramAdapter miniGramAdapter;
LinearLayoutManager linearLayoutManager;
ArrayList<MiniGram> miniGramArrayList = new ArrayList<>();
Bus bus = BusProvider.getInstance();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bus.register(this); //정류소 등록
minigram_recycler = findViewById(R.id.minigram_recycler);
//Retrofit 객체생성
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
/*addConverterFactory(GsonConverterFactory.create())은
Json을 우리가 원하는 형태로 만들어주는 Gson라이브러리 Retrofit2에 연결하는 것입니다 */
miniGramService = retrofit.create(MiniGramService.class);
miniGramAdapter = new MiniGramAdapter(MainActivity.this,miniGramArrayList);
linearLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
minigram_recycler.setLayoutManager(linearLayoutManager);
minigram_recycler.setAdapter(miniGramAdapter);
miniGramService.getMiniGram().enqueue(new Callback<List<MiniGram>>() {
@Override
public void onResponse(Call<List<MiniGram>> call, Response<List<MiniGram>> response) {
if(response.isSuccessful()) {
List<MiniGram> getMiniGrams = response.body();
for (MiniGram miniGram : getMiniGrams){
miniGramArrayList.add(miniGram);
}
miniGramAdapter.notifyDataSetChanged();
}else {
Log.d("MainiActivity", "failed");
}
}
@Override
public void onFailure(Call<List<MiniGram>> call, Throwable t) {
}
});
}
@Override
public void finish() {
super.finish();
bus.unregister(this); //이액티비티 떠나면 정류소 해제해줌
}
@Subscribe //이벤트버스에서 보낸 이벤트가 여기에 정착을 하는 정류소를 만든다고 생각
public void updateLike(HeartEvent heartEvent) {//public항상 붙여줘야함
miniGramService.updateLike(heartEvent.getId(), heartEvent.isLike()).enqueue(new Callback<MiniGram>() {
@Override
public void onResponse(Call<MiniGram> call, Response<MiniGram> response) {
if(response.isSuccessful()){
Log.d("like update", "sucess");
}else{
Log.d("like update", "failed");
}
}
@Override
public void onFailure(Call<MiniGram> call, Throwable t) {
Log.d("like update", "not connected");
}
});
}
}
+) TIP
매번 정류장을 등록하고 해제하는게 번거롭고 귀찮을 수 있습니다.
그런 경우 이와같이 액티비티를 하나만들고 이 BaseActivity를 otto를 사용하는 액티비티에서 AppCompactActivity대신 extends해주면 알아서 정류장이 등록 해제됩니다.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.squareup.otto.Bus;
public class BaseActivity extends AppCompatActivity {
Bus bus = BusProvider.getInstance();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bus.register(this);
}
@Override
public void finish() {
super.finish();
bus.unregister(this);
}
}
'안드로이드 > 자바 & Previous' 카테고리의 다른 글
[안드로이드] 버튼 중복클릭 방지하기 (0) | 2019.06.24 |
---|---|
[안드로이드] Realm 데이터베이스 정리 (0) | 2019.06.16 |
[안드로이드] Spanny 라이브러리 (0) | 2019.06.15 |
[안드로이드] Retrofit2 정리 예제 (19) | 2019.06.14 |
파이어베이스 FCM 노티피케이션(notification)하는 방법 정리 2019 (41) | 2019.06.12 |