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

标签 android multithreading

在我的应用程序中,我想进行蓝牙聊天。我在线程中遇到问题。在我的应用程序中,我的 Android 手机将用作具有阻塞语句的服务器

 socket=mServerSocket.accept();

为此,我创建了一个子线程,以便它单独运行。但在完成此子线程之前,主线程关闭并提供 Force Close,如果我使用 .join() 方法,它会挂断我的 UI

并行运行两个线程的解决方案是什么?

这是我的代码 主要 Activity

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();



            }
        });
}

}

蓝处理器

    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;
            }
        }

    }

    }

最佳答案

您可能会遇到崩溃,因为您正在工作线程上访问 textView。您需要使用 TextView.post(Runnable)为了避免这种情况发生。

实际上您应该使用可绑定(bind)的 Service做这种工作。您可以通过广播 Intent 或回调方法回传到 UI,这样您就不必担心旋转错误。

关于android - 使用线程时在android中获取强制关闭错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9393998/

相关文章:

android - 如何在发布的apk中使用minifyEnable?

android - 在 GreenDao 中,使用 OR 而不是 AND 构建连接查询

c++ - 线程中不可见的运行时错误

线程

android - 在纵向模式下将 Android DialogFragment 显示为对话框,在横向模式下显示为 Activity 的一部分

android - 按下后按钮绘制正常状态

java - 不同线程中的 DecimalFormat.format(double)

java - 通过多线程将二维数组传递给类

.net - 创建异步服务的正确模式是什么?

javascript - 使用 html5/javascript 将键盘设置为即使在 "go"按下时也保持打开状态?