0

TCP 소켓에서 작업 중입니다. 서버로부터 매 1 초마다 데이터를 수신하고 ListView에 화면에 표시해야합니다. 이것을 위해 AsyncTask를 사용했습니다.AsyncTask의 IllegalStateException입니다. 어댑터의 내용이 변경되었지만 listview가 알림을받지 못했습니다.

하지만 자주 IllegalStateException이 오류를 enter image description here

무엇입니까 내 코드 :

Handler handler = new Handler(); 
Timer timer = new Timer(); 

TimerTask doAsynchronousTask = new TimerTask() { 

    @Override 
    public void run() { 
     finalizer = new Runnable() { 
      public void run() { 
       try { 
        if (navBool) { 
         runOnUiThread(new Runnable() { 
          public void run() { 
           new RetriveStock().execute(); // AsyncTask. 
          } 
         }); 

        } 
       } catch (Exception e) { 
       } 
      } 
     }; 
     handler.post(finalizer); 
    } 
}; 
timer.schedule(doAsynchronousTask, 0, 1000); 

// AsyncTask를 클래스

public class RetriveStock extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected Void doInBackground(Void... params) { 
     message = client.clientReceive(1); // Here I receive data from server and stores it in "message" string variable. 
     printJson(); // FUNCTION WHICH UPDATE VALUES IN 'obj' OBJECT 
     runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       updateList();// FUNCTION WHICH UPDATE THE LISTVIEW UI. 
       adb.notifyDataSetChanged(); 
      } 
     }); 

     return null; 
    } 

    @Override 
    protected void onCancelled() { 
     super.onCancelled(); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 

       if (adb != null) { 
        lv.invalidateViews(); 
        lv.setAdapter(adb); 
        adb.notifyDataSetChanged(); 
        lv.requestLayout(); 

       } 


     super.onPostExecute(result); 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected void onProgressUpdate(Void... values) { 
     super.onProgressUpdate(values); 
    } 

} 

// 기능 JSON에있는 업데이트 값.

public void printJson() { 
    try { 
     JSONArray jsonArray = new JSONArray(message); 

     for (int i = 0; i < jsonArray.length(); i++) { 
      JSONObject json = jsonArray.getJSONObject(i); 


      String symbol = json.getString("Symbol_En"); 
      User obj = new User(); 
      boolean checkSymbol = false; 
      for (int j = 0; j < list.size(); j++) { 
       obj = list.get(j); 
       if (obj.getSymbol().equalsIgnoreCase(symbol)) { 
        checkSymbol = true; 
        break; 
       } 
      } 
      if (!checkSymbol) { 
       obj = new User(); 
       obj.Symbol_En = json.getString("Symbol_En"); 
       obj.Symbol_Ar = json.getString("Symbol_Ar"); 
       obj.AskPrice = json.getString("Ask"); 
       obj.BidPrice = json.getString("Bid"); 
       obj.AskQuantity = json.getString("AskQuantity"); 
       obj.High = json.getString("High"); 
       obj.Low = json.getString("Low"); 
       obj.Open = json.getString("Open"); 
       obj.Close = json.getString("Close"); 
       obj.PerChange = json.getString("PerChange"); 
       obj.NetChange = json.getString("NetChange"); 
       obj.Volume = json.getString("Volume"); 
       obj.Ltp = json.getString("LTP"); 
       obj.TimeStamp = json.getString("TimeStamp"); 
       obj.symbolId = json.getString("Id"); 

        list.add(obj); 
      } else { 

       obj.Symbol_En = json.getString("Symbol_En"); 
       obj.AskPrice = json.getString("Ask"); 
       obj.BidPrice = json.getString("Bid"); 
       obj.High = high + ""; 
       obj.Low = low + ""; 
       obj.Open = json.getString("Open"); 
       obj.Close = json.getString("Close"); 
       obj.PerChange = json.getString("PerChange"); 
       obj.NetChange = json.getString("NetChange"); 
       obj.Volume = json.getString("Volume"); 
       obj.Ltp = json.getString("LTP"); 
       obj.TimeStamp = json.getString("TimeStamp"); 
       obj.symbolId = json.getString("Id"); 

      } 

     } 
    } catch (JSONException e1) { 
     e1.printStackTrace(); 
    } 
} 

// LISTVIEW UI를 업데이트하는 기능.

public void updateList() { 
     adb = new ArrayAdapter<User>(DefaultMarketWatch.this, 
       R.layout.rssitemview, list) { 

      @Override 
      public View getView(final int position, View convertView, 
        ViewGroup parent) { 
       View view = convertView; 
       try { 
        if (null == view) { 
         LayoutInflater vi = (LayoutInflater) DefaultMarketWatch.this 
           .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
         view = vi.inflate(R.layout.rssitemview, null); 
        } 
        final User u = list.get(position); 
        if (null != u) { 
         final TextView title = (TextView) view 
           .findViewById(R.id.symbol); 
         final TextView persend = (TextView) view 
           .findViewById(R.id.persent); 
         final TextView ltp = (TextView) view 
           .findViewById(R.id.ltp); 
         final TextView high = (TextView) view 
           .findViewById(R.id.high); 
         final TextView low = (TextView) view 
           .findViewById(R.id.low); 
         final TextView persendBold = (TextView) view 
           .findViewById(R.id.persent_bold); 
         final TextView persendSup = (TextView) view 
           .findViewById(R.id.persent_sup); 

           ltp.setText(u.getLtp()); 
           title.setText(u.getSymbol()); 
           high.setText(u.getHigh()); 
           low.setText(u.getLow()); 
            persend.setText(u.getPerChange()); 

        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
       return view; 

      } 

     }; 
} 

답변

3

로그는

The content of the adapter is changed but listview did not receive notification. make sure content of your adapter is not modified from background thread but only from ui thread. 

당신은 doInBackground에서 updateList() // FUNCTION WHICH UPDATE THE LISTVIEW UI을 말한다. doInbackground이 백그라운드 스레드에서 호출됩니다. Ui 스레드에서 ui를 업데이트해야합니다. doInbackground 활동 또는 반환 결과의 방법 첫째로 나는 같은 짓을 onPostExecute

+0

에 업데이트 목록보기입니다

사용 runOnUiThread. 그러나 동일한 결과를 반환합니다. IllegalStateException. 이제 runOnUiThread로 updateList()를 수정했습니다. 한번 봐주세요. – user2085965

+0

@ user2085965 아직 잘못하지 않았습니다.'runOnUiThread'에'updateList'를 넣고 notifyDataSetChanged를 호출하여 업데이트시 listview를 새로 고칩니다. – Raghunandan

+0

@ user2085965 두 번째로 스냅 샷을 게시하지 마십시오. 예외 부분을 선택하고 스크린 샷의 오른쪽 상단에있는 자세한 정보 옆에있는 버튼을 사용하여 여기에 예외를 게시하십시오. – Raghunandan