应用程序因beginlistendata()函数中的looper.prepare()而崩溃

时间:2015-12-13 14:34:24

标签: android multithreading

    public class BluetoothActivity extends Activity {

// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        // Whenever a remote Bluetooth device is found
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // Add the name and address to an array adapter to show in a ListView
            adapter.add(bluetoothDevice.getName() + "\n"
                    + bluetoothDevice.getAddress());
        }
    }
};
//declaration
TextView myLabel;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
volatile boolean stopWorker;
private BluetoothAdapter mBluetoothAdapter;
private ListView listview;
private ArrayAdapter adapter;
private ToggleButton toggleButton;
private static final int REQUEST_ENABLE_BT =0;
private static final int DISCOVERABLE_DURATION = 0;
private static final int DISCOVERABLE_BT_REQUEST_CODE = 2;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.bluetooth_main);
    toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
    listview = (ListView) findViewById(R.id.listView);
    // ListView Item Click Listener
    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
            // ListView Clicked item value
            String  itemValue = (String) listview.getItemAtPosition(position);
            Toast.makeText(getApplicationContext(), "clicked", Toast.LENGTH_LONG).show();
            String MAC = itemValue.substring(itemValue.length() - 17);
            BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(MAC);
            // Initiate a connection request in a separate thread

            ConnectingThread t = new ConnectingThread(bluetoothDevice);
            t.start();
        }
    });


    adapter = new ArrayAdapter
            (this,android.R.layout.simple_list_item_1);
    listview.setAdapter(adapter);



    //verify bluetooth is supported on the device
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    // Device does not support Bluetooth
    if (mBluetoothAdapter == null) {
    }


}//end oncreate

public void onToggle(View view) {
    adapter.clear();

    if (toggleButton.isChecked()){
        //enable bluetooth
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            Toast.makeText(getApplicationContext(), "Turned on", Toast.LENGTH_LONG).show();
        }
        else
        {
            Toast.makeText(getApplicationContext(),"Already on", Toast.LENGTH_LONG).show();
            //To discover remote Bluetooth devices
            discoverDevices();
            // Make local device discoverable by other devices
            makeDiscoverable();
        }
    }//end of 1st if

    else{
        //turn off bluetooth
        mBluetoothAdapter.disable();
        adapter.clear();
        Toast.makeText(getApplicationContext(),"Turned off" ,Toast.LENGTH_LONG).show();
    }
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_ENABLE_BT) {
        // Bluetooth successfully enabled!
        if (resultCode == Activity.RESULT_OK) {
            Toast.makeText(getApplicationContext(), "Bluetooth is now enabled.",Toast.LENGTH_SHORT).show();

            // Make local device discoverable by other devices
            makeDiscoverable();
            // To discover remote Bluetooth devices
            Log.e("calldiscover", "func");
            discoverDevices();
            Log.e("Discover", "device");
            // Start a thread to create a  server socket to listen
            // for connection request
            Log.e("listenthread", "listenthread");
            ListeningThread t = new ListeningThread();
            Log.e("call", "t.start");
            t.start();
            Log.e("t.start", "over");
        }
        else {
            // RESULT_CANCELED as user refused
            Toast.makeText(getApplicationContext(), "Bluetooth is not enabled.",
                    Toast.LENGTH_SHORT).show();

            // Turn off togglebutton
            toggleButton.setChecked(false);
        }

    }//end of 1st if
}
protected void discoverDevices(){
    // To scan for remote Bluetooth devices
    if (mBluetoothAdapter.startDiscovery()) {Log.e("disc", "print");
        Toast.makeText(getApplicationContext(), "Discovering other bluetooth devices...", Toast.LENGTH_SHORT).show();
    }
    else {
        Log.e("print", "print");
        Toast.makeText(getApplicationContext(), "Discovery failed to start.", Toast.LENGTH_SHORT).show();
    }
}

protected void makeDiscoverable(){
    // Make local device discoverable
    Intent discoverableIntent = new
            Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVERABLE_DURATION);
    startActivityForResult(discoverableIntent, DISCOVERABLE_BT_REQUEST_CODE);
}

@Override
protected void onResume() {
    super.onResume();
    // Register the BroadcastReceiver for ACTION_FOUND
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    this.registerReceiver(broadcastReceiver, filter);
}

@Override
protected void onPause() {
    super.onPause();
    this.unregisterReceiver(broadcastReceiver);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}




private class ListeningThread extends Thread {
    private final BluetoothServerSocket bluetoothServerSocket;

    public ListeningThread() {
        BluetoothServerSocket temp = null;
        try {
            temp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(getString(R.string.app_name), uuid);

        } catch (IOException e) {
            e.printStackTrace();
        }
        bluetoothServerSocket = temp;
    }

    public void run() {
        BluetoothSocket bluetoothSocket;
        // This will block while listening until a BluetoothSocket is returned
        // or an exception occurs
        while (true) {
            try {
                Log.e("while", "over");
                bluetoothSocket = bluetoothServerSocket.accept();
                Log.e("bt", "accept");
            } catch (IOException e) {Log.e("error", "catch");
                break;
            }
            // If a connection is accepted
            if (bluetoothSocket != null) {
                Log.e("connection is accepted", "over");
                BluetoothActivity.this.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(BluetoothActivity.this, "Connected!", Toast.LENGTH_SHORT).show();

                    }
                });

                // Manage the connection in a separate thread

                try {Log.e("callserver", "close");
                    bluetoothServerSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }//end of while
    }

    // Cancel the listening socket and terminate the thread
    public void cancel() {
        try {Log.e("cancel", "socket");
            bluetoothServerSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 //Setting Up a Connecting Client
        private class ConnectingThread extends Thread {
             OutputStream mmOutputStream;
             InputStream mmInputStream;
            private final BluetoothSocket bluetoothSocket;
            private final BluetoothDevice bluetoothDevice;

            public ConnectingThread(BluetoothDevice device) {

                BluetoothSocket temp = null;
                bluetoothDevice = device;

                // Get a BluetoothSocket to connect with the given BluetoothDevice
                try { Log.e("click6", "click6");
                    temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                bluetoothSocket = temp;
            }

            public void run() {
                // Cancel any discovery as it will slow down the connection
                Log.e("click7", "click7");
                mBluetoothAdapter.cancelDiscovery();
                Log.e("click8", "click8");

                try {

                    // This will block until it succeeds in connecting to the device
                    // through the bluetoothSocket or throws an exception
                    bluetoothSocket.connect();
                    mmOutputStream = bluetoothSocket.getOutputStream();
                    mmInputStream = bluetoothSocket.getInputStream();
                    beginListenForData();
                    Log.e("listendata", "lsitendata");
                    BluetoothActivity.this.runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            Toast.makeText(BluetoothActivity.this, "Connected with Device!", Toast.LENGTH_SHORT).show();

                        }
                    });
                    Log.e("click9", "click9");
                } catch (IOException connectException) {
                    connectException.printStackTrace();
                    try {
                        bluetoothSocket.close();
                        Log.e("click6", "blueclose");
                    } catch (IOException closeException) {
                        closeException.printStackTrace();
                    }
                }


            }


     void beginListenForData()
            {
                final Handler handler = new Handler();
                final byte delimiter = 10; //This is the ASCII code for a newline character

                stopWorker = false;
                readBufferPosition = 0;
                readBuffer = new byte[1024];//It uses a 1024 bytes long buffer because it doesn't have any way of knowing the length of the input stream.
                workerThread = new Thread(new Runnable()
                {
                    public void run()
                    {
                        while(!Thread.currentThread().isInterrupted() && !stopWorker)
                        {
                            try
                            {
                                int bytesAvailable = mmInputStream.available();
                                if(bytesAvailable > 0)
                                {
                                    byte[] packetBytes = new byte[bytesAvailable];
                                    mmInputStream.read(packetBytes);
                                    for(int i=0;i<bytesAvailable;i++)
                                    {
                                        byte b = packetBytes[i];
                                        if(b == delimiter)
                                        {
                                            byte[] encodedBytes = new byte[readBufferPosition];
                                            System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
                                            final String data = new String(encodedBytes, "US-ASCII");
                                            readBufferPosition = 0;

                                            handler.post(new Runnable()
                                            {
                                                public void run()
                                                {

                                                    myLabel.setText(data);
                                                }
                                            });

                                        }
                                        else
                                        {
                                            readBuffer[readBufferPosition++] = b;
                                        }
                                    }
                                }
                            }
                            catch (IOException ex)
                            {
                                stopWorker = true;
                            }
                        }
                    }
                });

            workerThread.start();
        }

当我尝试调用beginListenForData()时,应用程序崩溃了错误状态,无法在未调用Looper.prepare()

的线程内创建处理程序

有谁知道什么是错的?我是android的新手。请帮忙。

下面的Bluetooth.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".BluetoothActivity">

    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textOn="Turn off Bluetooth"
        android:textOff="Turn on Bluetooth"
        android:id="@+id/toggleButton"
        android:onClick="onToggle"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true" />

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/listView"
        android:layout_alignParentStart="true"
        android:layout_marginStart="76dp"
        android:layout_below="@+id/toggleButton" />

    <TextView
        android:id="@+id/label"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Type here:"
        android:layout_below="@+id/toggleButton"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="66dp" />


</RelativeLayout>

1 个答案:

答案 0 :(得分:0)

beginListenForData()

中尝试此操作

替换

    final Handler handler = new Handler();

有了这个

    final Handler handler = new Handler(Looper.getMainLooper());