2012-06-20 4 views
0

업데이트 된 메시지를 찾기 위해 매 초마다 서버를 가져 오는 코드를 작성하려고합니다. 그러면 메시지가 텍스트보기로 표시됩니다. 텍스트보기에서 텍스트를 변경하지 않으면 정상적으로 실행됩니다. 스레드에서 textview를 변경하려고하면 충돌이 발생합니다. 내가 그것을 변경하지 않으면 스레드에서 잘 작동합니다.스레드에서 TextViews 텍스트를 어떻게 변경합니까?

스레드가 주 스레드 메모리에 액세스 할 수 없다고 가정하고 있습니까? 어떻게하면 인터넷을 통해로드 된 텍스트로 뷰의 텍스트를 설정할 수 있습니까?

아래 코드에서 나는 수면과 함께 무한 루프를하는 스레드를 가지고 있습니다. SendMessage라는 메서드를 호출합니다. 메시지 보내기는 인터넷을 통해 텍스트로로드되고 마지막에는보기로 업데이트하려고 시도합니다. 이 경우 예외가 발생합니다.

코드 :

public class cChat extends cBase implements OnClickListener { 
    /** Called when the activity is first created. */ 
     TextView mUsers; 
     TextView mComments; 
     int i=0; 

    @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.chat); 

      mUsers=(TextView) findViewById(R.id.viewusers);; 
      mComments=(TextView) findViewById(R.id.viewchats);; 

      Thread thread = new Thread() 
      { 
       @Override 
       public void run() { 
        try { 
         int t=0; 
         while(true) 
         { 
          SendMessage(); 
          sleep(1000*5); 
          t++; 
         } 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      }; 

      thread.start(); 

     } 


     public void onClick(View v) { 


      } // end function 



     // send a uypdate message to chat server 
     // return reply in string 
     void SendMessage() 
     { 


      try { 


      URL url = new URL("http://50.63.66.138:1044/update"); 
       System.out.println("make connection"); 

       URLConnection conn = url.openConnection(); 
       // set timeouts to 5 seconds 
       conn.setConnectTimeout(1000*5); 
       conn.setReadTimeout(5*1000); 
       conn.setDoOutput(true); 
       BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); 


      // String line; 
       String strUsers=new String(""); 
       String strComments=new String(""); 
       String line=new String(); 
       int state=0; 
       while ((line= rd.readLine() ) != null) { 
       switch(state){ 
       case 0: 
        if (line.contains("START USER")) 
        state=1; 
        if (line.contains("START COMMENTS")) 
        state=2; 
        break; 
       case 1: 
        if (line.contains("END USER")) 
         state=0; 
        else 
        { 
        strUsers+=line; 
        strUsers+="\n"; 
        } 
        break; 
       case 2: 
         if (line.contains("END COMMENTS")) 
          state=0; 
         else { 
         strComments+=line; 
         strComments+="\n"; 
         } 
         break; 
       } // end switch 
       } // end loop 

     // the next line will cause a exception 
       mUsers.setText(strUsers); 
       mComments.setText(strComments); 

     } catch (Exception e) { 
      i++; // use this to see if it goes here in debugger 
      // System.out.println("exception"); 
      // System.out.println(e.getMessage()); 
      } 

     } // end methed 
} 
+0

_thread_ 대신'AsyncTask'를 고려해야합니다. –

답변

0

당신은 UI/메인 쓰레드에 (보다 Runnable를) 작업을 게시하는 핸들러를 사용할 수 있습니다

private Handler handler = new Handler(); 

//... 

Thread thread = new Thread() 
{ 
@Override 
public void run() { 
    try { 
     int t=0; 
     while(true) 
     { 
      handler.post(new Runnable() { 
       @Override 
       public void run() { 
        SendMessage(); 
       } 
      }); 

      sleep(1000*5); 
      t++; 
     } 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
}; 
+0

안녕하세요, 코드에서 나는 SendMessage가 실행 중일 때 호출 될 것이라고 가정합니다. UI가 아닌 스레드를 만들었습니까?내가 물었던 이유는 나의 SendMessag가 정말 나쁜 버그를 가지고 있었고, ui frooz 때문이었다. 나는 그것이 다른 스레드에 있었으면 UI가 동결하지 않아야한다고 생각하겠습니까 ??? –

3

사용 runOnUiThread

YOUR_CURRENT_ACTIVITY.this.runOnUiThread(new Runnable() { 

     @Override 
     public void run() { 
     // the next line will cause a exception 
      mUsers.setText(strUsers); 
      mComments.setText(strComments); 
      //....YOUR UI ELEMENTS 
     } 
     }); 

같은 편집 : 당신은 하나의 다른 스레드에서 UI 위젯을 터치 할 수 runOnUiThread

+0

UIThread에서 스레드를 실행 하시겠습니까? UIThread를 차단하지 않을 것입니까? – Ixx

+0

예 runOnUiThread는 기본 UI를 차단하지 않습니다 스레드 –

+0

@lxx 문서보기 http://developer.android.com/reference/java/lang/Runnable.html –

0

문서를 참조 UI 스레드를 만드는 데 사용됩니다. 당신이 Activity에 대한 참조가있는 경우, 당신은 간단하게 수행 할 수 있습니다 strUsers을 필요로

activity.runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     mUsers.setText(strUsers); 
     mComments.setText(strComments); 
    } 
}); 

익명 클래스에 의해 액세스 할 수.

final String finalUseres = strUsers; 

run()finalUsers를 사용이를 위해 당신은 간단하게 할 수 있습니다.

0
the Andoid UI toolkit is not thread-safe. So, you 
must not manipulate your UI from a worker thread  

이 문제를 해결하기 위해 Android는 다른 스레드에서 UI 스레드에 액세스하는 여러 가지 방법을 제공합니다.

당신은 또한 AsyncTask를 사용할 수 있습니다 여기에 도움이 될 수 있습니다 방법의 목록입니다.

this tutorial on process and threads in android을 참조하십시오.

0

Service 연속/당기 서버에 데이터를 보낼 사용해보십시오. 이렇게하면 UI 스레드의로드가 줄어 듭니다.

관련 문제