2015-01-26 6 views
0

저는 작은 채팅 응용 프로그램을 작성했으며 AndroidAsync을 사용하여 응용 프로그램에서 WebSocket 클라이언트 기능을 사용하고 있습니다. 이미 나는 비 UI 스레드에서보기를 수정할 수 있음을 이해 한AndroidAsync - WebSocket.StringCallback()에서보기 업데이트

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
      at android.view.ViewRoot.checkThread(ViewRoot.java:2932) 
      at android.view.ViewRoot.focusableViewAvailable(ViewRoot.java:1712) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:452) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:452) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:452) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:452) 
      at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:452) 
      at android.view.View.setFlags(View.java:4614) 
      at android.view.View.setFocusableInTouchMode(View.java:3190) 
      at android.widget.AdapterView.checkFocus(AdapterView.java:694) 
      at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:789) 
      at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:31) 
      at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50) 
      at android.widget.ArrayAdapter.notifyDataSetChanged(ArrayAdapter.java:247) 
      at persilabtest.zulfigarov.com.chatapp.ChatActivity$1$1.onStringAvailable(ChatActivity.java:76) 
      at com.koushikdutta.async.http.WebSocketImpl$1.onMessage(WebSocketImpl.java:88) 
      at com.koushikdutta.async.http.HybiParser.emitFrame(HybiParser.java:420) 
      at com.koushikdutta.async.http.HybiParser.access$800(HybiParser.java:46) 
      at com.koushikdutta.async.http.HybiParser$5.onDataAvailable(HybiParser.java:197) 
      at com.koushikdutta.async.DataEmitterReader.handlePendingData(DataEmitterReader.java:24) 
      at com.koushikdutta.async.DataEmitterReader.onDataAvailable(DataEmitterReader.java:41) 
      at com.koushikdutta.async.Util.emitAllData(Util.java:22) 
      at com.koushikdutta.async.AsyncNetworkSocket.onReadable(AsyncNetworkSocket.java:146) 
      at com.koushikdutta.async.AsyncServer.runLoop(AsyncServer.java:788) 
      at com.koushikdutta.async.AsyncServer.run(AsyncServer.java:626) 
      at com.koushikdutta.async.AsyncServer.access$700(AsyncServer.java:41) 
      at com.koushikdutta.async.AsyncServer$13.run(AsyncServer.java:568) 

: 나는 예외가 발생 WebSocket.StringCallback().onStringAvailable(String)에서 내 목록보기를 수정하려고 할 때마다 그래서 문제입니다. 그러나 나는이 상황에서 내가 어떻게 그들을 업데이트 할 수 있는지 모른다.

public class ChatActivity extends ActionBarActivity 
{ 
    private static final String WS_ADDRESS = "ws://192.168.0.106:8084/TestChatServer/chat"; 

    @InjectView(R.id.btnSend) 
    Button btnSend; 

    @InjectView(R.id.lvChat) 
    ListView lvChat; 

    @InjectView(R.id.etMsg) 
    EditText etMsg; 

    List<String> mMessages = new ArrayList<String>(); 

    ArrayAdapter<String> adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_chat); 
     ButterKnife.inject(this); 
     adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mMessages); 
     lvChat.setAdapter(adapter); 

     AsyncHttpClient.getDefaultInstance() 
       .websocket(WS_ADDRESS, null, new AsyncHttpClient.WebSocketConnectCallback() 
       { 
        @Override 
        public void onCompleted(Exception ex, WebSocket webSocket) 
        { 

         if (ex != null) 
         { 
          ex.printStackTrace(); 
          return; 
         } 
         Log.d("myLogs", "OK"); 

         webSocket.setStringCallback(new WebSocket.StringCallback() 
         { 
          @Override 
          public void onStringAvailable(String s) 
          { 
           String newStr = s.replaceAll("(#+\\S+)", "<font color='#EE0000'>$1</font>"); 
           Log.d("myLogs", s + "\n" + newStr); 
           mMessages.add(newStr); 
           //This line causes the exception 
           adapter.notifyDataSetChanged(); 
          } 
         }); 
        } 
       }); 

    } 
} 

그래서, 내가 때마다 업데이트 내 목록보기를 얻을 수있는 방법 어떤 아이디어가 새로운 메시지 전달 : 여기 내 ChatActivity 코드입니까?

+0

가능한 중복 (HTTP : // 유래 .com/questions/5161951/android-only-the-original-thread-that-created-a-view-hierarchy-its-vi) –

답변

3

UI 스레드에서보기를 업데이트해야합니다. 이 같은 Activity.runOnUiThread()를 사용하여이 작업을 수행 할 수 있습니다 : 그것은 (뷰를 만든 스레드 이외의) 다른 스레드의 의견을 터치하려고하는 것을 감지하기 때문에

runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 

    //run your code that needs to update the UI here 

    } 
}); 

이 오류 Only the original thread that created a view hierarchy can touch its views 이유입니다. 하나 이상의 리소스가 동시에 무언가를 변경하려고 시도하는 경우 스레딩 문제가 발생할 수 있습니다.

없이 메인 스레드에서 adapter.notifyDataSetChanged();를 실행하지 마십시오
+0

고마워) 이제 작동 해.) –

+0

당신을 환영합니다! –

0

대신 사용

new Handler().post(new Runnable() { 
    @Override 
    public void run() { 
     adapter.notifyDataSetChanged() 
    } 
}); 
[안드로이드 "는 의견을 만질 수있는 뷰 계층 구조를 생성 만 원래 스레드."]의