EventBus發送消息後,onEvent中是否可以直接更新界面,如何更新。

編者:李國帥

qq:9611153 微信lgs9611153

2020/6/11

背景:

android用久了,慢慢覺得,EventBus和broadcast很相近,但EventBus可比廣播好用多了。

有個問題,在onEvent(XXXEvent event)函數裏,能不能直接更新界面View呢?

下面做了一個測試。

首先:

在線程中收到socket消息,然後發送一個訂閱事件

EventBusUtils.sendEvent(new XXXEvent(type));

 

EventBusUtils類在本文後面。

情景1:

在activity中響應訂閱事件,刷新列表,但是列表並沒有被刷新,但是不能正常調用

 

android開發中經常碰到這個問題,沒有出現任何問題,但是不會被執行,我們可以在日誌中看到錯誤,分清哪些是致命的,不可忽視的,哪些是次要的,誤報的。


 

@Subscribe

    public void onEvent(XXXEvent event) {

        //Log.d(TAG, "XXXActivity onEvent(XXXEvent event)");

        //adapter.initListView(contentBinding.rrvList, getContext());

        adapter.onRefresh();

    }

會出現

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

情景2:

可能是必須在ui線程才能刷新列表。

@Subscribe

    public void onEvent(XXXEvent event) {

        //Log.d(TAG, "XXXActivity onEvent(XXXEvent event)");


            new Handler().postDelayed(() -> {

           //如果需要等待服務器響應,馬上刷新列表數據可能不是最新數據。需要等待一段時間再去刷新數據

                //adapter.initListView(contentBinding.rrvList, getContext());

                adapter.onRefresh();

            }, 500);

         }

    }

 

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

由此可見new Handler()中是否可以更新ui呢?是可以的,但是需要在界面線程泵中執行。

 

需要修改爲 

@Subscribe

    public void onEvent(XXXEvent event) {

                 //Log.d(TAG, "XXXActivity onEvent(XXXEvent event)");


            new Handler().postDelayed(() -> {

                                     Looper.prepare();

                                     //adapter.initListView(contentBinding.rrvList, getContext());

                                      adapter.onRefresh();

                                     Looper.loop();

            }, 500);

         }

    }

情景3:

如果不需要等待,使用runOnUiThread則更好   

       runOnUiThread(new Runnable() {

                @Override

                public void run() {

                    //adapter.initListView(contentBinding.rrvConsult, getContext());

                    adapter.onRefresh();


                }

            });

EventBusUtils類


 

public class EventBusUtils {


    public static void register(Object context){

        if (!EventBus.getDefault().isRegistered(context)) {

            EventBus.getDefault().register(context);

        }

    }

    public static void unregister(Object context){

        if (EventBus.getDefault().isRegistered(context)) {

            EventBus.getDefault().unregister(context);

        }

    }

    public static void sendEvent(Object object){

        EventBus.getDefault().post(object);

    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章