notifyDataSetChanged is not working for Thread

1.4k views Asked by At

I am fetching messages from the server and storing in local db by using Service. I need to create new Thread for volley response if I won't do so the UI lags so much but the listview is updating. Now after creating new Thread the UI is not lagging anymore but its not updating the listview. Below is my service class code.

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();
        }
    });
}`

While on the other hand in fragment I want to notify my listview that the database has been updated by following code.

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

And I am notifying my listview by custom BaseAdapter.

ChatListAdapter.java

public void updateChatList(ArrayList<ChatListDataResponse> numbers){
    listDataResponses.clear();
    listDataResponses.addAll(numbers);
    this.notifyDataSetChanged();
    this.notifyDataSetInvalidated();
}
  • Result I am getting: For the very first time after storing the api response into local db the listview stays blank. And on everytime calling ChatService the listview is not updating.
  • Result I want: I want to notify the listview whenever ChatService gets called.
2

There are 2 answers

1
NehaK On

Try Handler to update UI, because Threads don't give confirmation to work on UI related work :

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

or try :

runOnUiThread(new Runnable() {
      public void run() {
        //UI updation code
      }
 });
3
Luca Nicoletti On

I would suggest you to use AsyncTask<Void, Void, Void>(), override doInBackground() with your code, and inside onPostExecute() perform the adapter.notifyDataSetChanged()