【问题标题】:How to refresh ListView content all time?如何始终刷新 ListView 内容?
【发布时间】:2017-12-03 09:23:23
【问题描述】:

我正在制作一个 android 应用程序,我每时每刻都从数据库中获取在线玩家。每个玩家都在 ListView 中占据一席之地,是一个项目列表。列表刷新如我所料,但是当我点击一个项目列表时,我的应用程序崩溃.我在 android 监视器中看到一个 IllegalStateException 我不知道为什么? 在下面的代码中,我从数据库下载数据,然后将其放入列表中。

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

            }
        }
    });
}

这是来自安卓监视器的消息

      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

我认为这可能是关键部分的问题,我不确定。所以我需要你的帮助来了解 listview 是如何工作的。

【问题讨论】:

    标签: android listview android-adapter


    【解决方案1】:

    首先,您被 runOnUIThread() 分散了注意力,响应侦听器可能会在不同的线程上调用,具体取决于您的 Mysingleton 的 OnlineRequest 处理程序。 其次,您在代码的最上面几行创建了一个未使用的 ArrayAdapter。 三、不需要每次都新建一个ArrayAdapter,只需要改变列表内容,调用notifyDataSetChanged()

    我认为下面的代码应该可以解决您的问题:

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

    【讨论】:

    • 在此代码中调用 notifyDataSetChanged();
    • 当你调用列表视图的setAdapter时,你不需要调用notifyDataSetChanged()。只有当你改变当前Adapter的内部列表时,才应该调用后一种方法。
    【解决方案2】:

    一旦您修改了列表,即通过删除或编辑其内容,您需要在适配器上调用“notifyDataSetChanged()”来通知您的适配器更改。在您的代码中,您在响应方法之外调用 notifyDataSetChanged。

    【讨论】:

    【解决方案3】:

    将 runOnUiThread 放在您的响应 Leinster 中,您可以在其中设置列表视图和适配器

    【讨论】:

      猜你喜欢
      • 2011-06-21
      • 2014-06-12
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      • 2019-01-01
      • 2019-02-05
      • 2016-02-21
      • 2021-05-04
      相关资源
      最近更新 更多