Android - (线程)应用程序将在我运行新线程时挂起

时间:2015-07-07 14:00:49

标签: android multithreading android-service

我的android应用程序中有3个活动。在第一个活动中,从配对设备列表中点击蓝牙设备,我启动服务以保持蓝牙连接对所有活动设备可见。在服务类中,我不断地从蓝牙设备读取数据,并且我将第二个活动绑定到服务类以读取接收的数据。

我无法在onServiceConnected()服务连接方法的方法之外获取活页夹的实例。所以我从onServiceConnected()方法调用用户定义的线程。通过这种方式,我可以从服务类中不断获取值。但该应用程序在成功执行几秒后不会响应。

它阻止了我认为的主线程。但我没有得到我需要修改代码的地方。下面的代码是我的第二个Activity(MainActivity)。 " bluetoothManager"是我的服务类。我还需要在第三项活动中完成类似的任务。

我没有得到问题是绑定还是线程。我需要调用Service连接类之外的线程。如果我这样做,我将获得空指针异常。所以我从onServiceConnected()函数调用线程,其中binder对象不为null。我必须使用布局mIsBound作为while循环。但现在它将永远是真的。请帮我。我是新手。

bluetoothManager.class
public class bluetoothManager extends Service{
final int handlerState = 0; // used to identify handler message
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder recDataString = new StringBuilder();
public ConnectedThread mConnectedThread;
static Handler bluetoothIn;

int bp;
String sensor0,sensor1; 
static Handler  mHandler;
// SPP UUID service - this should work for most devices
private static final UUID BTMODULEUUID = UUID
        .fromString("00001101-0000-1000-8000-00805F9B34FB");
  IBinder mBinder = new LocalBinder();
 @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }


 public class LocalBinder extends Binder {
   bluetoothManager getService() {        
        return bluetoothManager.this;           
    }
}




    @Override
    public void onCreate() {
       /// Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
       // flag="created";
    }
    private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {

        return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
        // creates secure outgoing connecetion with BT device using UUID
    }
    public String getBPM(){  
            return sensor1;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, " MyService Started", Toast.LENGTH_LONG).show();
       final String address=intent.getStringExtra("address");          
        final int currentId = startId;

        if(address!=null)
        {
            btAdapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothDevice device = btAdapter.getRemoteDevice(address);            
        try {
            btSocket = createBluetoothSocket(device);               
        } catch (IOException e) {
            Toast.makeText(getBaseContext(), "Socket creation failed",
                    Toast.LENGTH_LONG).show();
        }
        // Establish the Bluetooth socket connection.
        try {
            btSocket.connect();
        } catch (IOException e) {
            try {
                btSocket.close();
            } catch (IOException e2) {
                // insert code to deal with this
            }
        }
        mConnectedThread = new ConnectedThread(btSocket);
        mConnectedThread.start();

        // I send a character when resuming.beginning transmission to check
        // device is connected
        // If it is not an exception will be thrown in the write method and
        // finish() will be called
        mConnectedThread.write("x");
        }
        bluetoothIn = new Handler() {
            public void handleMessage(android.os.Message msg) {
        if (msg.what == handlerState) { // if message is what we want
            String readMessage = (String) msg.obj; // msg.arg1 = bytes
                                                    // from connect
                                                    // thread
            recDataString.append(readMessage); // keep appending to
                                                // string until ~
            int endOfLineIndex = recDataString.indexOf("~"); // determine
                                                                // the
                                                                // end-of-line
            if (endOfLineIndex > 0) { // make sure there data before ~
                String dataInPrint = recDataString.substring(0,
                        endOfLineIndex); // extract string
                //txtString.setText("Data Received = " + dataInPrint);
                /*int dataLength = */dataInPrint.length(); // get length of
                                                        // data received
                /*txtStringLength.setText("String Length = "
                        + String.valueOf(dataLength));*/

                if (recDataString.charAt(0) == '#') // if it starts with
                                                    // # we know it is
                                                    // what we are
                                                    // looking for
                {

                     sensor0 = recDataString.substring(1,3);
                     // get
                     sensor1=sensor0;

                    Log.d("bpm", sensor0);
                                        }
                recDataString.delete(0, recDataString.length()); // clear
                                                                    // all
                                                                    // string
                                                                    // data
                // strIncom =" ";
                dataInPrint = " ";
            }
        }
    }

};

 // get Bluetooth
                                                    // adapter


        return currentId;
    }
    private class ConnectedThread extends Thread {
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        // creation of the connect thread
        public ConnectedThread(BluetoothSocket socket) {
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                // Create I/O streams for connection
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {
            byte[] buffer = new byte[256];
            int bytes;

            // Keep looping to listen for received messages
            while (true) {
                try {
                    bytes = mmInStream.read(buffer); // read bytes from input
                                                        // buffer
                    String readMessage = new String(buffer, 0, bytes);
                    // Send the obtained bytes to the UI Activity via handler
                    bluetoothIn.obtainMessage(handlerState, bytes, -1,
                            readMessage).sendToTarget();

                } catch (IOException e) {
                    break;
                }
            }
        }

            // write method
            public void write(String input) {
                byte[] msgBuffer = input.getBytes(); // converts entered String into
                                                        // bytes
                try {
                    mmOutStream.write(msgBuffer); // write bytes over BT connection
                                                    // via outstream
                } catch (IOException e) {
                    // if you cannot write, close the application
                    Toast.makeText(getBaseContext(), "Connection Failure",
                            Toast.LENGTH_LONG).show();                      

                }
            }


    }
    @Override
    public void onRebind(Intent intent) {
    Log.v("myservice", "in onRebind");
    super.onRebind(intent);
    }
    @Override
    public boolean onUnbind(Intent intent) {
    Log.v("myapp", "in onUnbind");
    return true;
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    Log.v("myservice", "in onDestroy");

    }   


}

MainActivity.java

 public class MainActivity extends Activity {

    private ServiceConnection mConnection;
    TextView  sensorView0;

    boolean mIsBound;
    bluetoothManager bm;
    private Handler bpmHandler;
    private ServiceConnection mConnection;

    final int handlerState = 0; // used to identify handler message

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sensorView0 = (TextView) findViewById(R.id.bpm);
        bpmHandler=new Handler(){
            public void handleMessage(android.os.Message msg) {
                if (msg.what == handlerState) {
                    String s=(String)msg.obj;
                    sensorView0.setText("BPM="+s);
                }
            }
        };
    }

    @Override
    public void onResume() {
        super.onResume();
        mConnection= new ServiceConnection() {
            @Override
            public void onServiceDisconnected(ComponentName name) {
                mIsBound = false;
                bm=null;
            }

            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                LocalBinder myBinder = (LocalBinder)service;
                mIsBound = true;
                bm=myBinder.getService();
                mConnectedService=new ConnectedService(mIsBound);
                mConnectedService.start();
            }
        };

        Intent intent = new Intent(this, bluetoothManager.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

    }
    private class ConnectedService extends Thread {
        final boolean bound;

        public  ConnectedService(boolean mIsBound){

            bound =mIsBound;

        }
        public void run() {
            String s;
            while (bound) {
                s= bm.getBPM();
                Message msg = new Message();
                msg.what =handlerState ;
                msg.obj=s;  MainActivity.this.bpmHandler.sendMessage(msg);
            }
        }
    };

    @Override
    public void onPause() {
        super.onPause();
        unbindService(mConnection);
        mIsBound = false;
    }
}

1 个答案:

答案 0 :(得分:0)

我觉得connectedservice线程代码导致了这个问题。而不是继续竞争grtBPM方法,为什么不在有变化时发布消息。您可以使用本地广播管理器从服务广播消息并捕获活动中的消息并相应地更新UI。 connectedservice线程连续运行并继续将消息发布到处理程序,这会导致主线程上的负载。