У меня есть 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;
}
}
Является ли ANR? Что вы видите в логарифме? – 7383
Ничего не будет отображаться в logcat.When мы нажмем кнопку «Назад», это не сработает. Если мы нажимаем более одного раза, ANR будет возникать. - @ 7383 –
Лучше отправить код Bluetooth-менеджера, чтобы понять проблему. – 7383