Sakis Paligiannis
Sakis Paligiannis

Reputation: 65

How to refresh ListView content all time?

I am making an android application and i take from database everymoment players who are online.Every player take a place in ListView, is an item list.The list refresh as i expected but when i click on an item list my application crashes.I see in the android monitor an IllegalStateException and i dont know why.I think that because i use the listview when i change the content and when i press the button at the same time.Can you help me someone or suggest something else to do? In the code below i download from database the data and after that i put it in the list.

public void onclickRefreshfunction()  {

    num = -1;

    runOnUiThread(new Runnable() {

        @Override
        public void run() {

            if (lock == 1) {

                lock = 0;

                ArrayAdapter<String> adapter = new ArrayAdapter<String>(OnLinePlayerActivity.this,
                        android.R.layout.simple_list_item_1, android.R.id.text1, list_of_onlineplayer);

                adapter.clear();
                adapter.notifyDataSetChanged();

                list_of_levels.clear();
                list_of_onlineplayer.clear();
                list_of_usernames.clear();

                Response.Listener<String> responseListener = new Response.Listener<String>() {

                    @Override
                    public void onResponse(final String response) {

                        try {

                            JSONObject jsonResponse = new JSONObject(response);
                            JSONArray usernamearray = jsonResponse.getJSONArray("list_of_usernames");
                            JSONArray levelarray = jsonResponse.getJSONArray("list_of_levels");

                            for (int i = 0; i < usernamearray.length(); i++) {

                                String name = usernamearray.getString(i);

                                if (name.equals(username)) {

                                    num = i;
                                    continue;

                                }

                                list_of_usernames.add(name);

                            }

                            for (int i = 0; i < levelarray.length(); i++) {

                                String level = levelarray.getString(i);

                                if (i == num) {

                                    continue;

                                }

                                list_of_levels.add(level);

                            }

                            for (int i = 0; i < list_of_usernames.size(); i++) {

                                list_of_onlineplayer.add("  Παίκτης  "+list_of_usernames.get(i) + "  επίπεδο  " + list_of_levels.get(i));

                            }

                            listView = (ListView) findViewById(R.id.list);
                            ArrayAdapter<String> adapter = new ArrayAdapter<String>(OnLinePlayerActivity.this,
                                    android.R.layout.simple_list_item_1, android.R.id.text1, list_of_onlineplayer);

                            listView.setAdapter(adapter);

                            lock = 1;

                        } catch (JSONException e) {

                            e.printStackTrace();

                        }
                    }
                };
                Response.ErrorListener error = new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                        Log.w("error with volley", "error");
                        onclickRefreshfunction();

                    }
                };

                OnlineRequest onlineRequest = new OnlineRequest(responseListener , error);
                //  RequestQueue queue = Volley.newRequestQueue(OnLinePlayerActivity.this);
                //  queue.add(onlineRequest);
                Mysingleton.getmInstance(getApplicationContext()).addToRequestque(onlineRequest);

            }
        }
    });
}

Here is the message from android monitor

      12-03 10:50:46.371 17346-17346/? E/MessageQueue-JNI: java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131558534, class android.widget.ListView) with Adapter(class android.widget.ArrayAdapter)]
                                                     at android.widget.ListView.layoutChildren(ListView.java:1566)
                                                     at android.widget.AbsListView.onTouchUp(AbsListView.java:4814)
                                                     at android.widget.AbsListView.onTouchEvent(AbsListView.java:4610)
                                                     at android.view.View.dispatchTouchEvent(View.java:8135)
                                                     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2425)
                                                     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2149)
                                                     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2295)
                                                     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1622)
                                                     at android.app.Activity.dispatchTouchEvent(Activity.java:2565)
                                                     at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
                                                     at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
                                                     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2243)
                                                     at android.view.View.dispatchPointerEvent(View.java:8343)
                                                     at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4769)
                                                     at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4635)
                                                     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4193)
                                                     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4247)
                                                     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4216)
                                                     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4327)
                                                     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4224)
                                                     at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4384)
                                                     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4193)
                                                     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4247)
                                                     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4216)
                                                     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4224)
                                                     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4193)
                                                     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6567)
                                                     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6484)
                                                     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6455)
                                                     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6420)
                                                     at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6647)
                                                    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java
           12-03 10:50:46.381 17346-17346/? E/AndroidRuntime: FATAL EXCEPTION: main
                                               Process: com.example.sakis.loginregister, PID: 17346
                                               java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131558534, class android.widget.ListView) with Adapter(class android.widget.ArrayAdapter)]
                                                   at android.widget.ListView.layoutChildren(ListView.java:1566)
                                                   at android.widget.AbsListView.onTouchUp(AbsListView.java:4814)
                                                   at android.widget.AbsListView.onTouchEvent(AbsListView.java:4610)
                                                   at android.view.View.dispatchTouchEvent(View.java:8135)
                                                   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2425)
                                                   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2149)
                                                   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431)
                                                   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2164)
                                                   at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2295)
                                                   at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1622)
                                                   at android.app.Activity.dispatchTouchEvent(Activity.java:2565)
                                                   at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
                                                   at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
                                                   at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2243)
                                                   at android.view.View.dispatchPointerEvent(View.java:8343)
                                                   at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4769)
                                                   at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4635)
                                                   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4193)
                                                   at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4247)
                                                   at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4216)
                                                   at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4327)
                                                   at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4224)
                                                   at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4384)
                                                   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4193)
                                                   at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4247)
                                                   at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4216)
                                                   at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4224)
                                                   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4193)
                                                   at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6567)
                                                   at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6484)
                                                   at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6455)
                                                   at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6420)
                                                   at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6647)
                                                at a
                                                at a

I think that maybe is a problem of critical section i am not sure.So i need your help to understand how listview working.

Upvotes: 0

Views: 56

Answers (3)

Arman Safikhani
Arman Safikhani

Reputation: 945

First of all, you are being distracted by runOnUIThread(), the response listeners might be called on a different thread, depending on your Mysingleton's OnlineRequest handler. Second, you are creating an unused ArrayAdapter at top lines of your code. Third, You do not need to create a new ArrayAdapter each time, just change the list content and call notifyDataSetChanged()

I think the below code should fix your problem:

    public void onclickRefreshfunction()  {
    num = -1;
    if (lock == 1) {
        lock = 0;

        Response.Listener<String> responseListener = new Response.Listener<String>() {
            @Override
            public void onResponse(final String response) {
                list_of_levels.clear();
                list_of_onlineplayer.clear();
                list_of_usernames.clear();

                try {
                    JSONObject jsonResponse = new JSONObject(response);
                    JSONArray usernamearray = jsonResponse.getJSONArray("list_of_usernames");
                    JSONArray levelarray = jsonResponse.getJSONArray("list_of_levels");

                    for (int i = 0; i < usernamearray.length(); i++) {

                        String name = usernamearray.getString(i);
                        if (name.equals(username)) {
                            num = i;
                            continue;
                        }

                        list_of_usernames.add(name);
                    }

                    for (int i = 0; i < levelarray.length(); i++) {
                        String level = levelarray.getString(i);
                        if (i == num) {
                            continue;
                        }
                        list_of_levels.add(level);
                    }

                    for (int i = 0; i < list_of_usernames.size(); i++) {
                        list_of_onlineplayer.add("  Παίκτης  "+list_of_usernames.get(i) + "  επίπεδο  " + list_of_levels.get(i));
                    }

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            listView = (ListView) findViewById(R.id.list);
                            ArrayAdapter<String> adapter = new ArrayAdapter<String>(OnLinePlayerActivity.this,
                                    android.R.layout.simple_list_item_1, android.R.id.text1, list_of_onlineplayer);

                            listView.setAdapter(adapter);
                        }
                    });
                    lock = 1;

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        };
        Response.ErrorListener error = new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.w("error with volley", "error");
                onclickRefreshfunction();
            }
        };

        OnlineRequest onlineRequest = new OnlineRequest(responseListener , error);
        //  RequestQueue queue = Volley.newRequestQueue(OnLinePlayerActivity.this);
        //  queue.add(onlineRequest);
        Mysingleton.getmInstance(getApplicationContext()).addToRequestque(onlineRequest);
    }
}

Upvotes: 1

Suraj Nair
Suraj Nair

Reputation: 1847

Put runOnUiThread inside your response Leinster where you setting list view and adapter

Upvotes: 0

HaroldSer
HaroldSer

Reputation: 2065

Once you have modified the list, i.e. by removing or editing its content you need to call "notifyDataSetChanged()" on the adapter to notify your adapter of the changes. In your code you are calling notifyDataSetChanged outside the response method.

Upvotes: 0

Related Questions