2017-12-03 189 views
0

我正在做一個android應用程序,我從數據庫everymoment在線的球員。每個球員在ListView中佔據一個位置,是一個項目列表。列表刷新如我所料,但是當我點擊一個項目列表我的應用程序崩潰。我在android監視器中看到IllegalStateException,我不知道爲什麼。我認爲這是因爲我在更改內容和同時按下按鈕時使用了listview。可以幫助我某人還是建議其他內容? 在下面的代碼中,我從數據庫中下載數據,然後將其放入列表中。如何刷新ListView內容的所有時間?

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

      } 
     } 
    }); 
} 

下面是Android的顯示器

 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 

我想,也許是至關重要的部分我是不是有問題的消息sure.So我需要你的幫助,以瞭解如何列表視圖的工作。

回答

0

首先,你正在被runOnUIThread(),響應聽衆可能被要求在不同的線程,這取決於你Mysingleton的OnlineRequest分心內runOnUiThread處理程序。 其次,您在代碼的頂部行創建一個未使用的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); 
    } 
} 
+0

在此代碼中調用notifyDataSetChanged(); –

+0

當您調用列表視圖的setAdapter時,您不需要調用notifyDataSetChanged()。 只有當你改變當前適配器的內部列表,你應該叫後一種方法。 – Arman

+0

阿爾曼非常感謝。 –

0

一旦你通過刪除或編輯的內容修改的列表,即你需要調用「notifyDataSetChanged()」的適配器上,通知您的修改適配器。在你的代碼中,你在響應方法外調用notifyDataSetChanged。

+0

你能張貼的例子? –

+0

見Android SDK中的官方文檔在這裏:https://developer.android.com/reference/android/widget/ArrayAdapter.html#notifyDataSetChanged() –

0

把你的迴應倫斯特,你設置列表視圖和適配器