使用线程时在android中获取强制关闭错误

时间:2012-02-22 11:35:09

标签: android multithreading

在我的应用程序中,我想做蓝牙聊天。我遇到了线程问题。在我的应用程序中,我的Android手机将作为具有阻止声明的服务器工作

 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 个答案:

答案 0 :(得分:1)

您可能正在崩溃,因为您正在访问工作线程上的textView。你需要使用TextView.post(Runnable)来实现这一点。

实际上你应该使用一个可绑定的Service来做这种工作。您可以通过广播意图或回调方法回发到UI,这样您就不必担心轮换错误了。

答案 1 :(得分:0)

您是否在子线程的构造函数中执行长操作?每个长操作必须在run()方法中完成。