Android 使用EventBus進行Fragment和Activity通訊

本文介紹EventBus的基本使用,以及用於Fragment和Activity之間通訊。 
github地址: https://github.com/greenrobot/EventBus 版本是 EventBus-2.4.0 release 
EventBus是基於訂閱和發佈的一種通訊機制,使用流程以下:git

  • 實例化EventBus對象
  • 註冊訂閱者
  • 發佈消息
  • 接受消息

對應代碼

EventBus eventBus = new EventBus();
eventBus.register(subscriber object);//註冊訂閱者
訂閱者對象中必須有 onEvent public 方法
public void onEvent(Object event){
   //接收消息
}
eventBus.post(event);//發送消息

應用到Activity和Fragment中

由於訂閱者必須有onEvent方法,所以咱們建立一個基類讓onEvent方法做爲抽象方法github

public abstract class BaseFragment extends Fragment {

    public BaseFragment() {
    }

    public abstract void onEvent(MyEvent eventData);

}

MainActivity

public class MainActivity extends FragmentActivity  {

    public Button btn;
    public EventBus eventBus;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.btn);
        eventBus = new EventBus();

        FragmentManager fm = getSupportFragmentManager();
        MyFragment myFragment = new MyFragment();
        fm.beginTransaction().replace(R.id.container, myFragment).commit();

        eventBus.register(myFragment);//註冊訂閱者 MyFragment

        btn.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                List<String> list = new ArrayList<String>();
                list.add("test string");
                MyEvent myEvent = new MyEvent();
                myEvent.eventType = 1;
                myEvent.data = list;
                eventBus.post(myEvent);//發佈消息

                myEvent = new MyEvent();
                myEvent.eventType = 2;
                myEvent.data = new MyCallBack();//接口回調做爲引用
                eventBus.post(myEvent);//發佈消息
            }
        });

    }

    //此時MainActivity做爲訂閱者
    public void onEvent(MyEvent event) {
        Log.d("", "onEvent >> callback main>>>" + event.data);
    }

    //回調接口也能夠作爲事件數據
    class MyCallBack implements DataCallBack {

        @Override
        public void onCallback(MyEvent eventData) {
            Log.d("", "eventData >>>> " + eventData);
        }

    }
}

封裝的消息MyEvent

public class MyEvent {
    public MyEvent() {
    }
    public int eventType;//可能類型有不少種,數據也不同
    public Object data;//數據對象

}

MyFragment

public class MyFragment extends BaseFragment {

    private DataCallBack actCallback;
    private EventBus eventBus;

    public MyFragment() {
        setHasOptionsMenu(true);
        eventBus = new EventBus();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_main, null);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        view.findViewById(R.id.call).setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                if (actCallback != null) { //獲得接口後 回調一下
                    MyEvent event = new MyEvent();
                    event.data = "this is fragment:" + MyFragment.this;
                    actCallback.onCallback(event);//調用回調
                }
            }
        });
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (getActivity() != null) {
            eventBus.register(getActivity());//事件訂閱者註冊,訂閱者爲MainActivity
        }
    }

    @Override
    public void onEvent(MyEvent event) { 
        int type = event.eventType;
        if (type == 1) {
            Log.d("", "onEvent type 1:" + event.data);
        }
        else if (type == 2) {
            Log.d("", "onEvent type 2:" + (event.data instanceof DataCallBack));
            if (event.data instanceof DataCallBack) {
                actCallback = ((DataCallBack) event.data);//獲得回調

                //發消息給MainActivity
                MyEvent event2 = new MyEvent();
                event2.data = "call main activity method";
                eventBus.post(event2);//發佈消息
            }
        }
    }
}

通常讓Fragment調用Activity的方法有一下幾種ide

  • 建立Fragment的時候把MainActivity引用傳給Fragment,其實經過getActivity()也能獲取到實例
  • 建立Fragment的時候傳入一個Handler實例,在Fragment中sendMessage也是能夠的
  • 建立Fragment的時候傳入一個實例化接口,做爲回調

我以爲用接口的方式更加好,耦合性算是比較低的一種。當Fragment pop後 getActivity()獲取的引用爲NULL,傳入Handler實例是能夠的,但有些時候你可能用不上Handler這個東西。post

EventBus使用仍是比較簡單的,下降了代碼耦合性,只須要在onEvent中處理數據便可。this

相關文章
相關標籤/搜索