ashish gabhane
ashish gabhane

Reputation: 43

Getting force close error in android when using threading

In my application i want to do bluetooth chat. I'm facing a problem in threading. In my application my android phone will work as server which has a blocking statement

 socket=mServerSocket.accept();

for this purpose i've created a child thread so that it will run separately. But before finishing this child thread main thread goes down giving Force Close and if i use the .join() method it hangs up my UI.

What is the solution to run both threads parallel?

this is my code main 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();



            }
        });
}

}

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

    }

    }

Upvotes: 1

Views: 421

Answers (2)

Jeremy Edwards
Jeremy Edwards

Reputation: 14740

You're probably getting a crash because you're accessing a textView on the worker thread. You'll need to use TextView.post(Runnable) to make that not happen.

In reality you should be using a bindable Service to do this kind of work. You can post back to the UI via broadcast intents or callback methods, That way you don't have to worry about rotation bugs.

Upvotes: 1

Sly
Sly

Reputation: 2101

Are you performing a long operation in the constructor of your children thread? Each long operation must be done in the run() method.

Upvotes: 0

Related Questions