2013-06-23 24 views
0

我有一個ListView,我從Android的MySQL數據庫中加載所有項目,並顯示這些項目。由於列表需要更新,因此在活動中,我使用Asynctask函數每15秒更新一次並更新ListView。還有一個滾動條,因爲可能有很多項目,這裏是錯誤發生的地方。如果我通過滾動條上下滾動,它會很順利。但是,如果我正在使用滾動條並且同時活動嘗試訪問數據庫以加載更新的項目,則應用程序將停止。ListView中的數據庫錯誤:應用程序已停止

這裏是日誌:

06-23 15:36:32.867: E/AndroidRuntime(7788): FATAL EXCEPTION: main 
    06-23 15:36:32.867: E/AndroidRuntime(7788): java.lang.IndexOutOfBoundsException: Invalid index 14, size is 0 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at java.util.ArrayList.get(ArrayList.java:304) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.SimpleAdapter.bindView(SimpleAdapter.java:147) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.SimpleAdapter.createViewFromResource(SimpleAdapter.java:126) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.SimpleAdapter.getView(SimpleAdapter.java:114) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.AbsListView.obtainView(AbsListView.java:2445) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.ListView.makeAndAddView(ListView.java:1769) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.ListView.fillUp(ListView.java:706) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.ListView.fillGap(ListView.java:645) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5530) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3509) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.widget.AbsListView.onTouchEvent(AbsListView.java:3906) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.View.dispatchTouchEvent(View.java:7340) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2179) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1914) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2113) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1466) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.app.Activity.dispatchTouchEvent(Activity.java:2468) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2061) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.View.dispatchPointerEvent(View.java:7525) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3368) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3300) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4392) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4370) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4474) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:163) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4442) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4493) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.Choreographer.doCallbacks(Choreographer.java:555) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.Choreographer.doFrame(Choreographer.java:523) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.os.Handler.handleCallback(Handler.java:615) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.os.Handler.dispatchMessage(Handler.java:92) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.os.Looper.loop(Looper.java:137) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at android.app.ActivityThread.main(ActivityThread.java:4895) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at java.lang.reflect.Method.invokeNative(Native Method) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at java.lang.reflect.Method.invoke(Method.java:511) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761) 
    06-23 15:36:32.867: E/AndroidRuntime(7788):  at dalvik.system.NativeStart.main(Native Method) 

感謝您的幫助

編輯:這是我用來刷新列表視圖每15秒代碼: @Override

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.all_candidatos); 
     StrictMode.ThreadPolicy policy = new StrictMode. ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); 

     boolean isReachable = false; 
     try{ 
      isReachable = InetAddress.getByName("192.168.1.41").isReachable(200); 
     } catch (Exception e){ 
      Log.e("InetAddress", e.getMessage()); 




     }finally { 
      if (isReachable) { 

       new CargarCandidatos().execute(); 
     timer(); 


      }else{ 
       Toast.makeText(getApplicationContext(), R.string.errorserver, Toast.LENGTH_LONG).show(); 
      } 

     } 
     setListAdapter(adapter); 

     candidatosList = new ArrayList<HashMap<String, String>>(); 



    } 
// 
// 
    public void timer(){ 
     new CountDownTimer(tiempo, 1000) { 

       public void onTick(long millisUntilFinished) { 

       } 

       public void onFinish() { 
        candidatosList.clear(); 
        new CargarCandidatos().execute(); 


        timer(); 

       } 
      }.start();} 




    class CargarCandidatos extends AsyncTask<String, Void, String> { 


     @Override 
     protected void onPreExecute() { 
      if(!isFinishing()){ 
      super.onPreExecute(); 
      pDialog = new ProgressDialog(Monitorizacion.this); 
      pDialog.setMessage("Monitorizando ..."); 
      pDialog.setIndeterminate(false); 
      pDialog.setCancelable(false); 
      pDialog.show(); 
     } 
     } 


     protected String doInBackground(String... args) { 




       try { 
        monitorizar(); 
       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace();} 
       return null; 




     } 


     protected void onPostExecute(String file_url) { 
    pDialog.dismiss(); 
      runOnUiThread(new Runnable() { 
       public void run() { 

        adapter = new SimpleAdapter(
          Monitorizacion.this, candidatosList, 
          R.layout.list_item, new String[] { TAG_NSERIE, 
            TAG_DNI, TAG_NOMBRE, TAG_TEST, TAG_PREGUNTA, TAG_BATERIA,TAG_CORRECTAS, TAG_ERRORES}, 
          new int[] { R.id.id, R.id.dni, R.id.nombre, R.id.test, R.id.pregunta, R.id.bateria, R.id.correctas, R.id.fallos}); 

        adapter.notifyDataSetChanged(); 
        setListAdapter(adapter); 


       } 
      }); 

     } 

    } 
    public void monitorizar() throws Exception{ 
     try { 
      List<NameValuePair> params = new ArrayList<NameValuePair>(); 
      JSONObject json = jParser.makeHttpRequest(url_candidatos, "GET", params); 
      int success = json.getInt(TAG_SUCCESS); 

      if (success == 1) { 

       candidatos = json.getJSONArray(TAG_CANDIDATOS); 

       for (int i = 0; i < candidatos.length(); i++) { 
        JSONObject c = candidatos.getJSONObject(i); 

        String nserie = c.getString(TAG_NSERIE); 
        String dni = c.getString(TAG_DNI); 
        String nombre = c.getString(TAG_NOMBRE); 
        String test = c.getString(TAG_TEST); 
        String pregunta = c.getString(TAG_PREGUNTA); 
        String bateria = c.getString(TAG_BATERIA); 
        String correctas = c.getString(TAG_CORRECTAS); 
        String errores = c.getString(TAG_ERRORES); 

        HashMap<String, String> map = new HashMap<String, String>(); 

        map.put(TAG_NSERIE, nserie); 
        map.put(TAG_DNI, dni); 
        map.put(TAG_NOMBRE, nombre); 
        map.put(TAG_TEST, test); 
        map.put(TAG_PREGUNTA, pregunta); 
        map.put(TAG_BATERIA, bateria); 
        map.put(TAG_CORRECTAS, correctas); 
        map.put(TAG_ERRORES, errores); 
        candidatosList.add(map); 
       } 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 



    } 
} 

編輯: 問題是,如果我向上或向下滾動列表視圖,那時會調用asynctask函數來訪問dat基地,錯誤發生,應用程序停止。

邁克爾·布切爾解決方案: 從我的理解我與邁克爾·布切爾給出的一塊提醒的解決:

public void timer(){ 
     new CountDownTimer(tiempo, 1000) { 

       public void onTick(long millisUntilFinished) { 

       } 

       public void onFinish() { 
        new CargarCandidatos().execute(); 


        timer(); 

       } 
      }.start();} 




    class CargarCandidatos extends AsyncTask<String, Void, String> { 


     @Override 
     protected void onPreExecute() { 
      if(!isFinishing()){ 
      super.onPreExecute(); 
      pDialog = new ProgressDialog(Monitorizacion.this); 
      pDialog.setMessage("Monitorizando ..."); 
      pDialog.setIndeterminate(false); 
      pDialog.setCancelable(false); 
      pDialog.show(); 
     } 
     } 


     protected String doInBackground(String... args) { 




       try { 
        monitorizar(); 
       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace();} 
       return null; 




     } 


     protected void onPostExecute(String file_url) { 
    pDialog.dismiss(); 
      runOnUiThread(new Runnable() { 
       public void run() { 

        adapter = new SimpleAdapter(
          Monitorizacion.this, candidatosList, 
          R.layout.list_item, new String[] { TAG_NSERIE, 
            TAG_DNI, TAG_NOMBRE, TAG_TEST, TAG_PREGUNTA, TAG_BATERIA,TAG_CORRECTAS, TAG_ERRORES}, 
          new int[] { R.id.id, R.id.dni, R.id.nombre, R.id.test, R.id.pregunta, R.id.bateria, R.id.correctas, R.id.fallos}); 

        adapter.notifyDataSetChanged(); 
        setListAdapter(adapter); 



       } 
      }); 

     } 

    } 
    public void monitorizar() throws Exception{ 
     try { 
      List<NameValuePair> params = new ArrayList<NameValuePair>(); 
      JSONObject json = jParser.makeHttpRequest(url_candidatos, "GET", params); 
      ArrayList<HashMap<String, String>> temp; 
      temp = new ArrayList<HashMap<String, String>>(); 


      int success = json.getInt(TAG_SUCCESS); 

      if (success == 1) { 

       candidatos = json.getJSONArray(TAG_CANDIDATOS); 

       for (int i = 0; i < candidatos.length(); i++) { 
        JSONObject c = candidatos.getJSONObject(i); 

        String nserie = c.getString(TAG_NSERIE); 
        String dni = c.getString(TAG_DNI); 
        String nombre = c.getString(TAG_NOMBRE); 
        String test = c.getString(TAG_TEST); 
        String pregunta = c.getString(TAG_PREGUNTA); 
        String bateria = c.getString(TAG_BATERIA); 
        String correctas = c.getString(TAG_CORRECTAS); 
        String errores = c.getString(TAG_ERRORES); 

        HashMap<String, String> map = new HashMap<String, String>(); 

        map.put(TAG_NSERIE, nserie); 
        map.put(TAG_DNI, dni); 
        map.put(TAG_NOMBRE, nombre); 
        map.put(TAG_TEST, test); 
        map.put(TAG_PREGUNTA, pregunta); 
        map.put(TAG_BATERIA, bateria); 
        map.put(TAG_CORRECTAS, correctas); 
        map.put(TAG_ERRORES, errores); 
        temp.add(map); 
        candidatosList = temp; 
       } 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 



    } 
} 
+1

顯示代碼的相關部分。我的第一個猜測:你嘗試更新GUI線程之外的GUI部分 –

+0

是的,我想這可能是錯誤的部分,但我不知道我該如何解決它。我已更新代碼 – Katherine99

回答

1

onPostExecute()創建它得到candidatosList數據適配器。 SimpleAdapter現在預計只有在以後立即調用notifyDataSetChanged()時纔會更改此數據(僅在主線程上發生更改和調用)。

在你的計時器的onFinish()你叫candidatosList.clear()onFinish()運行在主線程,所以這是確定的),但你不要撥打notifyDataSetChanged()

更好的方法:

不要叫candidatosList.clear()可言,而不是創建一個新的ArrayList(例如所謂的「temp」)在開始的monitorizar(),與接收到的數據填充它和monitorizar()作爲最後一步設定candidatosList = temp。爲了在任何情況下都能正常工作,candidatosList應該被聲明爲volatile(因爲它被多個線程使用)。

+0

嗨邁克爾,我已經做了或多或少你說的,但錯誤仍然存​​在。問題是,如果我向上或向下滾動列表視圖,並且當時調用asynctask函數來訪問數據庫,則會發生錯誤。 – Katherine99

+0

@ Katherine99然後你應該顯示你的新代碼(也許是新的錯誤日誌) –

+0

嗨邁克爾,我已經用你的解決方案更新了這個問題,至少現在它可以工作。謝謝 – Katherine99

相關問題