2012-02-22 3 views
1

내 응용 프로그램에서 블루투스 채팅을하고 싶습니다. 스레딩 문제가 있습니다. 내 응용 프로그램에서 내 안드로이드 전화는 별도로 실행할 수 있도록 내가 자식 스레드를 생성 한이 목적을 위해 차단 문스레딩을 사용할 때 안드로이드에서 강제 종료 오류 발생

socket=mServerSocket.accept(); 

을 가지고 서버로 작동합니다. 그러나이 자식 스레드 주 스레드를 끝내기 전에 Force Close주는 그리고 내가 .join() 메서드를 사용하는 경우 내 UI 응답하지 않습니다.

두 스레드를 병렬로 실행하는 솔루션은 무엇입니까?

이 내 코드 주요 활동

package com.my.bluechat_2_1; 

import android.app.Activity; 
import android.bluetooth.BluetoothAdapter; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 
import android.widget.Toast; 

public class BlueChat extends Activity { 
/** Called when the activity is first created. */ 
private BlueHandler btHandler=null; 
private BluetoothAdapter btAdapter = null; 
private Context context=this; 
TextView chatWindow=null; 


    @Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    chatWindow=(TextView)findViewById(R.id.textView1); 
    doStart(); 
} 

private void doStart(){ 
    Button btnStart=(Button)findViewById(R.id.button1); 
    btnStart.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 

       // Get local Bluetooth adapter 
       btAdapter = BluetoothAdapter.getDefaultAdapter(); 
       // If the adapter is null, then Bluetooth is not supported 
       if(btAdapter == null) 
       { 
        Toast.makeText(context, "Device does not support Bluetooth", Toast.LENGTH_LONG).show(); 
       } 
       if (!btAdapter.isEnabled()) { 
        Intent discoverableIntent = new 
        Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 
        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); 
        startActivity(discoverableIntent); 
       } 

       chatWindow.append("Waiting for connection...\n"); 
       btHandler=new BlueHandler(context,chatWindow,btAdapter); 
       Thread acceptThread=new Thread(btHandler); 
       acceptThread.start(); 



      } 
     }); 
} 

} 

BlueHandler

package com.my.bluechat_2_1; 

    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.OutputStream; 
    import java.util.UUID; 

    import android.bluetooth.BluetoothAdapter; 
    import android.bluetooth.BluetoothServerSocket; 
    import android.bluetooth.BluetoothSocket; 
    import android.content.Context; 
    import android.widget.TextView; 
    import android.widget.Toast; 

public class BlueHandler implements Runnable{ 
    // Name for the SDP record when creating server socket 
    private static final String SMARTCAM_BT_SERVICE_NAME = "SmartCam"; 

    // Unique UUID for this application 
    private static final UUID SMARTCAM_BT_SERVICE_UUID = UUID.fromString("95b82690-4c94-11e1-b86c-0800200c9a66"); 

    private BluetoothAdapter btAdapter = null; 
    private BluetoothServerSocket btServerSocket = null; 
    private BluetoothSocket btSocket = null; 
    private InputStream btInputStream=null; 
    private Context contextObj=null; 
    private TextView textView; 



    public BlueHandler(Context contextObj,TextView textView,BluetoothAdapter btAdapter){ 
     this.contextObj=contextObj; 
     this.btAdapter=btAdapter; 
     this.textView=textView; 

     try { 
      btServerSocket=this.btAdapter.listenUsingRfcommWithServiceRecord(SMARTCAM_BT_SERVICE_NAME, SMARTCAM_BT_SERVICE_UUID); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      Toast.makeText(this.contextObj, "Service not created", Toast.LENGTH_LONG); 
     } 
    } 

    @Override 
    public void run() { 
     // TODO Auto-generated method stub 
     textView.append("Inside child thread.\n"); 
     textView.append(btServerSocket+"\n"); 

     while (true) { 
       try { 
        btSocket = btServerSocket.accept(); 
       } catch (IOException e) { 
        break; 
       } 
       // If a connection was accepted 
       if (btSocket != null) { 
        // Do work to manage the connection (in a separate thread) 
        try { 
         btServerSocket.close(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
        break; 
       } 
      } 

     textView.append("Connected.\n"); 

     try { 
      btInputStream=btSocket.getInputStream(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     byte[] buffer = new byte[1024]; // buffer store for the stream 
     String s; 
     int bytes; // bytes returned from read() 

     // Keep listening to the InputStream until an exception occurs 
     while (true) { 
      try { 
       // Read from the InputStream 

       bytes=btInputStream.read(buffer); 
       s= new String(buffer); 
       // Send the obtained bytes to the UI Activity 
       textView.append("received ::" +s+"\n"); 
      } catch (IOException e) { 
       break; 
      } 
     } 

    } 

    } 
+2

질문에 게시 할 수있는 logcat 출력이 있습니까? –

답변

0

당신이 당신의 아이들의 생성자에서 긴 작업을 수행 할이 스레드입니까? 각 long 연산은 run() 메소드에서 수행해야합니다.

+0

코드 ..plz를 추가했습니다. –

+0

Jeremy가 말했듯이 ** UI 스레드 (예 : TextView 콘텐츠)를 UI 스레드 = 주 스레드에서만 ** 업데이트 **해야합니다. – Sly

+0

게다가, 생성자에서 메서드를 수행하는 데 오랜 시간이 걸립니까? 아직 블루투스 API를 사용하지 않았습니다. 다음 줄 앞뒤에 로그를 추가 할 수 있습니다. btServerSocket = this.btAdapter.listenUsingRfcommWithServiceRecord (SMARTCAM_BT_SERVICE_NAME, SMARTCAM_BT_SERVICE_UUID); – Sly

1

작업자 스레드에서 textView에 액세스 중이기 때문에 충돌이 발생했을 수 있습니다. 그렇게하지 않으려면 TextView.post(Runnable)을 사용해야합니다.

실제로 이런 종류의 작업을 수행하려면 바인드 가능 Service을 사용해야합니다. 브로드 캐스트 인 텐트 또는 콜백 메소드를 통해 UI에 다시 게시 할 수 있습니다. 이렇게하면 로테이션 버그에 대해 걱정할 필요가 없습니다.

관련 문제