2015-07-07 2 views
0

У меня есть 3 действия в моем приложении для Android. В первом действии, при щелчке Bluetooth-устройства из списка сопряженных устройств, я запускаю службу, чтобы поддерживать соединение Bluetooth видимым для всех активов. В классе службы я непрерывно читаю данные с устройства bluetooth, и я привязываю второе действие к классу службы для чтения полученных данных.Android - (Thread) приложение будет висеть при запуске нового потока

Я не могу получить экземпляр связующего за пределами метода подключения к службе onServiceConnected(). Поэтому я вызываю пользовательский поток из метода onServiceConnected(). Таким образом, я получаю значения непрерывно из класса обслуживания. Но приложение не ответит через несколько секунд после успешного выполнения.

Он блокирует основную нить, я думаю. Но я не понимаю, где мне нужно изменить код. Код ниже - это моя вторая активность (MainActivity). «bluetoothManager» - мой класс обслуживания. Мне также нужно сделать аналогичную задачу и в третьей деятельности.

Я не понимаю, связана ли проблема с привязкой или нитью. Мне нужно вызвать поток вне класса Connection. Если я это сделаю, я получу исключение нулевого указателя. Поэтому я вызываю поток из функции onServiceConnected(), где объект связывания не равен нулю. Я должен использовать boolean 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; 
    } 
} 
+0

Является ли ANR? Что вы видите в логарифме? – 7383

+0

Ничего не будет отображаться в logcat.When мы нажмем кнопку «Назад», это не сработает. Если мы нажимаем более одного раза, ANR будет возникать. - @ 7383 –

+0

Лучше отправить код Bluetooth-менеджера, чтобы понять проблему. – 7383

ответ

0

Я чувствую код connectedservice нить вызывает проблему. Вместо того, чтобы постоянно запускать метод grtBPM, почему бы вам не опубликовать сообщение только после изменения. Вы можете использовать локальный диспетчер радиовещания для трансляции сообщения из службы и улавливать его в действии и обновлять интерфейс. Нить connectedservice работает непрерывно и продолжает отправлять сообщение обработчику, который вызывает нагрузку на основной поток.

Смежные вопросы