notifyDataSetChanged不适用于Thread

时间:2016-12-27 16:37:55

标签: android multithreading listview custom-adapter notifydatasetchanged

我从服务器获取消息并使用Service存储在本地数据库中。我需要为凌空响应创建新的线程,如果我不这样做,UI会滞后这么多但是listview正在更新。现在,在创建新的线程后,UI不再滞后,但它不会更新列表视图。以下是我的服务类代码。

ChatService.java

StringRequest stringRequest=new StringRequest(Request.Method.GET, url.replaceAll(" ","%20"), new Response.Listener<String>() {
        @Override
        public void onResponse(final String response) {
            networkThread=new Thread(new Runnable() {
                @Override
                public void run() {
                    Gson gson=new Gson();
                    chatResponse=gson.fromJson(response,GetAllChatResponse.class);
                    for (Object obj:chatResponse.getData()) {
                        Log.d("conversation response",""+((ChatDataResponse) obj).getMessage());
                        sqLiteDataProvider.insertMessage(true,(ChatDataResponse) obj);
                    }
                    Log.d("conver","ok");
                    sendWaResult();
                }
            });
            networkThread.start();

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.d("convo error",""+error.getMessage());
        }
    });
    MySingleton.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);

public void sendWaResult(){
    final Intent intent=new Intent(KYOWA_RESULT);
    try{
        Looper.prepare();
    } catch (Exception e) {}
    Handler handler = new Handler();
    handler.post(new Runnable() {
        @Override
        public void run() {
            waBroadcastManager.sendBroadcast(intent);
            stopSelf();
        }
    });
}`

另一方面,在片段中,我想通过以下代码通知我的列表视图已更新数据库。

ChatFragment.java

   receiver=new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                ChatFragment.this.getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        getChat();
                    }
                });

            }
        };
private void getChat() {
    new AsyncTask<Void,Void,ArrayList<ChatListDataResponse>>(){

        @Override
        protected ArrayList<ChatListDataResponse> doInBackground(Void... voids) {
            return sqLiteDataProvider.getChatList();
        }

        protected void onPostExecute(ArrayList<ChatListDataResponse> list)
        {
            listDataResponses = list;
            if (chatListAdapter==null){
                chatListAdapter=new ChatListAdapter(getContext(),listDataResponses);
                mListView.setAdapter(chatListAdapter);
            }else {
                chatListAdapter.updateChatList(listDataResponses);
            }
        }
    }.execute();

我正在通过自定义BaseAdapter通知我的列表视图。

ChatListAdapter.java

public void updateChatList(ArrayList<ChatListDataResponse> numbers){
    listDataResponses.clear();
    listDataResponses.addAll(numbers);
    this.notifyDataSetChanged();
    this.notifyDataSetInvalidated();
}
  • 我得到的结果:在将api响应存储到本地数据库后,第一次列表视图保持空白。每次调用ChatService时,listview都不会更新。
  • 我想要的结果:我想在每次调用ChatService时通知列表视图。

2 个答案:

答案 0 :(得分:2)

尝试使用Handler来更新UI,因为线程不会对UI相关工作进行确认:

new Handler().post(new Runnable() {
      public void run() {
        //UI updation code
      }
 });

或尝试:

runOnUiThread(new Runnable() {
      public void run() {
        //UI updation code
      }
 });

答案 1 :(得分:1)

我建议您使用AsyncTask<Void, Void, Void>(),使用代码覆盖doInBackground(),然后在onPostExecute()内执行 adapter.notifyDataSetChanged()