본문 바로가기
안드로이드/개발자 일상

안드로이드 이벤트 버스 ( otto 라이브러리 )

by 차누감 2020. 4. 29.

특정 이벤트를 발생시키고 싶은 경우에 쓰이는 라이브러리입니다.

ex) 데이터를 보냈을 때, 그 시점에 특정 실행을 하고 싶은 경우

activity <-> fragment 또는 Service에서 activity 간의 데이터 전달 등등

이런 경우 Intent, Bundle 등 여러 가지 방법이 있지만 너무 불편하다고 느끼시는 분들도 있을 겁니다.

 

여기서 편리하게 전역 변수처럼 데이터를 전달하고, 전달된 시점에서 특정 메서드를 실행할 수 있습니다.

 

자세한 사항은 아래 라이브러리 주소 링크로 확인하세요.

https://github.com/square/otto

 

square/otto

An enhanced Guava-based event bus with emphasis on Android support. - square/otto

github.com

Gradle

dependencies {
    implementation 'com.squareup:otto:1.3.8'//otto
}

 

버스 클래스를 만들어 줍니다.

1
2
3
4
5
6
7
8
9
public class BusProvider {
    public static final Bus bus = new Bus(ThreadEnforcer.ANY);
 
    public static Bus getInstance(){
        return bus;
    }
    public BusProvider() {
    }
}// BusProvider class..
 
 

 

그리고 내가 전달할 데이터를 담는 클래스를 만들어 줍니다. (예제에서는 boolean 값을 전달하겠습니다.)

1
2
3
4
5
6
7
8
9
10
11
12
public class BusEvent {
 
    boolean flag;
 
    public BusEvent(boolean flag ) {
        this.flag = flag;
    }
 
    public boolean isFlag() {
        return flag;
    }
 
}// BusEvent class..

 

<예시로 fragment -> Activity로 데이터 전달을 하겠습니다.>

 

데이터를 전달받을 곳에 선언을 해줍니다.  ( 예로 Activity   5번째 줄, 그리고 사용을 했다면 14번째 줄  )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        BusProvider.getInstance().register(this);
 
    }// onCreate()..
    
 
@Override
    protected void onDestroy() {
        super.onDestroy();
 
        BusProvider.getInstance().unregister(this);
    }// onDestroy()..
 
 
 
 

그리고 데이터를 받을 때, 실행되는 메서드를 작성합니다.  ( Activity)

1
2
3
4
5
6
7
    @Subscribe
    public void busStop(BusEvent busEvent) {//public항상 붙여줘야함
        if(busEvent.isFlag()) {
          // bus로 전달 받은 값이 true일 경우 실행.
        }
    }
 
 

 

 

마지막으로 내가 데이터를 보낼 곳에서 Boolean 값을 줍니다. ( 예로 fragment )

BusProvider.getInstance().post(new BusEvent(true));

예제를 통해 알아보겠습니다, ( 미리 Fragment는 구현을 했습니다. )

Fragment에서 이벤트를 발생하여 MainActivity 버튼을 제어하겠습니다.

 

<현재 모습> 화면에 MainActivity 영역과 Fragment가 보입니다.

이제 otto 라이브러리를 추가합니다.

 implementation 'com.squareup:otto:1.3.8'//otto

 

 

그리고 버스 클래스와 내가 전달할 데이터를 담는 클래스를 만들어 줍니다. ( Class 2개 생성 )

BusProvider Class

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

package com.example.ex_otto_event_bus;

 

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() {

    }

}// BusProvider

BusEvent Class

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package com.example.ex_otto_event_bus;

 

public class BusEvent {

    boolean flag;

 

    public BusEvent(boolean flag ) {

        this.flag = flag;

    }

 

    public boolean isFlag() {

        return flag;

    }

}// BusEvent Class..

 

이제 fragment에서 이벤트를 발생 했을 시,  MainActivity의 버튼을 변경하겠습니다.

 

MainActivity.java

[ 30번째 줄, 64번째 줄, 76번째 줄이 Bus 관련 코드입니다. ]

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.example.ex_otto_event_bus;
 
import androidx.annotation.NonNull;
 
 
 
public class MainActivity extends AppCompatActivity {
 
    private FragmentManager fragmentManager = getSupportFragmentManager();
    public HomeFragment fragmentHome = new HomeFragment();
    public UserFragment fragmentUser = new UserFragment();
 
    BottomNavigationView bottomNavigationView;
 
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        BusProvider.getInstance().register(this);   // Bus
 
        button=findViewById(R.id.button);
 
        bottomNavigationView=findViewById(R.id.navigationView);
 
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.frameLayout, fragmentHome).commitAllowingStateLoss();  //첫 번째 화면 지정
 
        bottomNavigationView.setOnNavigationItemSelectedListener(new ItemSelectedListener());
 
 
 
    }// onCreate()..
 
 
    class ItemSelectedListener implements BottomNavigationView.OnNavigationItemSelectedListener{
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            FragmentTransaction transaction = fragmentManager.beginTransaction();
 
            switch(menuItem.getItemId())
            {
                case R.id.home:
                    transaction.replace(R.id.frameLayout, fragmentHome).commitAllowingStateLoss();
                    break;
                case R.id.user:
                    transaction.replace(R.id.frameLayout, fragmentUser).commitAllowingStateLoss();
                    break;
            }
            return true;
        }
    }// ItemSelectedListener class..
 
    // Bus 이벤트 발생 시
    @Subscribe
    public void busStop(BusEvent busEvent) {
        Log.e("TAG","bus");
        if(busEvent.isFlag()) {
            button.setText("버튼 활성화");
        }
    }//  busStop()..
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        BusProvider.getInstance().unregister(this);      // Bus
    }
}// MainActivity class..
 
 

 

Fragment에서 데이터를 전달하며 이벤트를 발생시킵니다.

[ 27번째 줄 Bus 관련 코드입니다. ]

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
31
32
33
package com.example.ex_otto_event_bus;
 
 
 
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
 
public class HomeFragment extends Fragment {
    Button bt_event;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_home,container,false);
 
        bt_event=view.findViewById(R.id.bt_event);
        bt_event.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 이벤트 발생 버튼을 눌렀을 경우
                BusProvider.getInstance().post(new BusEvent(true)); // 버스에 true 값 전달
            }
        });
        return view;
    }// onCreateView()..
}// HomeFragment..
 
 

<실행 화면> Fragment 이벤트 발생 시, MainActivity에 이벤트 발생 시점에 값을 전달받을 수 있습니다.

댓글