发表于: 2018-10-05 23:12:13

0 651


一、今天完成的事情

    1. 解决了昨天下拉刷新数据不能正常加载到RecyclerView的问题

       原因:适配器中的数据虽然更新了,但RecyclerView并不知道,需要调用Adapter的notifyDataSetChanged()                    方法来更新RecyclerView,当适配器的内容改变时会强制调用getView()来刷新每个Item的内容。

       然后我又在添加了adapter.notifyDataSetChanged()


                    @Override

                    public void onRefresh() {

    

                            @Override

                            public void run () {

                                Toast.makeText(getActivity(), "正在刷新", Toast.LENGTH_SHORT).show();

                                Log.d("通知", "开始查询");

                                queryData(0, STATE_REFRESH);

                                adapter.notifyDataSetChanged();

                                swipeRefreshLayout.setRefreshing(false);

                            }

                        }

    

    结果还是不行,后来又查了半天才发现原因,使用notifyDataSetChanged()有一些要注意的地方:

       (1)adapter适配的数据必须是同一个对象

                 比如myAdapter = new MyAdapter(data)中的data必须是同一个对象。

       (2)数据刷新时要通知主线程刷新UI(我的问题就出在这里)

                Android实现View更新有两组方法,分别是invaliDate和postInvaliDate,前者在UI线程中使用,后者在

          非 UI线程即子线程中使用,在子线程调用invaliDate 方法会导致线程不安全,invaliDate 方法会通知 view 

          立 即重绘,刷新界面,假如子线程在用 invaliDate刷新界面的同时UI线程也在用 invaliDate 刷新界面,这

          样会不导致界面的刷新不能同步。

                解决方法是子线程发送消息通知UI线程更新UI

                UI线程接受消息并执行adapter.notifyDataSetChanged(),UI得到更新:

private Handler mHandler = new Handler() {
@Override
   public void handleMessage(Message msg) {
   super.handleMessage(msg);
       if (msg.what == CHANGE_UI) {
           Log.d("通知:", "接受成功");
           workerAdapter.notifyDataSetChanged();
           Log.d("通知:", "UI更新");
       }
   }
};

            子线程发送更新UI的消息:

Log.d("", "数据查询已完成,通知主线程更新UI");
mHandler.sendEmptyMessage(CHANGE_UI);

           

       安卓的消息机制

      

       Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。

       Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例 如更新UI等。 MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际 意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。

       Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。

       Thread:线程,负责调度整个消息循环,即消息循环的执行场所。 


  参考Android子线程更新UI的方法总结,这篇博文讲得很详细。

二、明天计划的事情

      实现上拉加载和条件筛选菜单。


三、遇到的问题

       如何设定子线程中 方法的执行顺序?


四、收获

      学会了如何在子线程中更新UI,其实并不是把更新UI的逻辑写在子线程中,子线程只是发送消息通知UI线程更新UI,具体的更新UI的逻辑要写在UI线程里。



返回列表 返回列表
评论

    分享到