我有一个显示传感器值的活动,并从onSensorChanged
方法将它们发送到同步队列。我在发布到队列时有一个超时,以便在队列阻塞时onSensorChanged
方法不会阻塞。我期待按下后退按钮时将调用onPause
方法,但不是,并且屏幕只是挂起而不返回上一个屏幕。知道为什么会这样吗?
顺便说一下,当队列没有阻塞(数据被订阅者删除)然后一切按预期工作时,按下后退按钮时会调用onPause
。
public void onSensorChanged(SensorEvent event) {
TextView tvX = (TextView) findViewById(R.id.textViewRemLinAccX);
TextView tvY = (TextView) findViewById(R.id.textViewRemLinAccY);
TextView tvZ = (TextView) findViewById(R.id.textViewRemLinAccZ);
String x = String.format(format, event.values[0]);
String y = String.format(format, event.values[1]);
String z = String.format(format, event.values[2]);
tvX.setText(x);
tvY.setText(y);
tvZ.setText(z);
try {
if (btConnection.isRunning()) {
Log.i(TAG, "+++ queue values");
queue.offer(constructData(x, y, z), 1, TimeUnit.SECONDS);
}
} catch (InterruptedException e) {
Log.e(TAG, "+++ err " + e.toString());
}
}
答案 0 :(得分:0)
如果您使用其他操作阻止UI(当您在主线程上执行某些操作时),则后退按钮将不起作用,您应该在后台线程上执行任何需要时间的操作。
答案 1 :(得分:0)
虽然我不太确定我是怎么做的,但似乎已经解决了,所以已经包含了其他人使用的代码。我做了很多重组,以确保正确清理连接资源,现在按下后退按钮时调用onPause和onDestroy方法。
Fyi,此活动打开蓝牙连接并将传感器数据发送到另一台计算机,用于控制LEGO NXT机器人。
package uk.co.moonsit.apps.sensors.remote;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
import uk.co.moonsit.apps.sensors.R;
import uk.co.moonsit.bluetooth.BluetoothConnection;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.WindowManager;
import android.widget.TextView;
public class RemoteLinearAccelerationActivity extends Activity implements
SensorEventListener {
private static final String TAG = "RemoteLinearAccelerationActivity";
private BlockingQueue<String> queue;
private SensorManager mSensorManager;
private Sensor mLinAcc;
private String format = "%.3f";
private String type;
private BluetoothConnection btConnection;
private String delimiter = "|";
private String cr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_remote_linear_acceleration);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
byte[] crb = new byte[1];
crb[0] = 13;
cr = new String(crb);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mLinAcc = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
queue = new SynchronousQueue<String>();
type = "LinAcc";
btConnection = new BluetoothConnection(queue, "00001101-0000-1000-8000-00805F9B34FB", "<MAC address here>", "11", "28,13");
Log.i(TAG, "+++ onCreate ");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.remote_linear_acceleration, menu);
return true;
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
@Override
public void onSensorChanged(SensorEvent event) {
TextView tvX = (TextView) findViewById(R.id.textViewRemLinAccX);
TextView tvY = (TextView) findViewById(R.id.textViewRemLinAccY);
TextView tvZ = (TextView) findViewById(R.id.textViewRemLinAccZ);
String x = String.format(format, event.values[0]);
String y = String.format(format, event.values[1]);
String z = String.format(format, event.values[2]);
tvX.setText(x);
tvY.setText(y);
tvZ.setText(z);
try {
String msg = constructData(x, y, z);
if (btConnection.isRunning()) {
Log.i(TAG, "+++ queue values");
queue.offer(msg, 10, TimeUnit.SECONDS);
}
} catch (InterruptedException e) {
Log.e(TAG, "+++ err " + e.toString());
}
}
private String constructData(String x, String y, String z) {
StringBuilder sb = new StringBuilder();
sb.append(type + delimiter);
sb.append(x + delimiter);
sb.append(y + delimiter);
sb.append(z);
sb.append(cr);
return sb.toString();
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "+++ onPause unregisterListener ");
mSensorManager.unregisterListener(this);
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "+++ onResume registerListener ");
mSensorManager.registerListener(this, mLinAcc, SensorManager.SENSOR_DELAY_NORMAL);
Log.i(TAG, "+++ onResume start btConnection");
new Thread(btConnection).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "+++ onDestroy closing btConnection");
btConnection.stop();
}
}
package uk.co.moonsit.bluetooth;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import uk.co.moonsit.messaging.BeginEndEnvelope;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
//import android.os.ParcelUuid;
import android.util.Log;
public class BluetoothConnection implements Runnable {
private static final String TAG = "BluetoothConnection";
private final BlockingQueue<String> queue;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothDevice device;
private BluetoothSocket clientSocket;
private DataInputStream in = null;
private DataOutputStream out = null;
private String address;
private boolean isConnected = false;
private BeginEndEnvelope envelope;
private String uuid;
private boolean isRunning = true;
public BluetoothConnection(BlockingQueue<String> q, String ud, String a,
String start, String end) {
uuid = ud;
queue = q;
address = a;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
envelope = new BeginEndEnvelope(start, end);
}
private void getDevice() throws IOException {
device = mBluetoothAdapter.getRemoteDevice(address);
}
private void getSocket() throws IOException {
clientSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
mBluetoothAdapter.cancelDiscovery();
}
private boolean connect() {
if (!isConnected) {
Log.i(TAG, "+++ connecting");
try {
getSocket();
Log.i(TAG, "+++ b4 connect");
clientSocket.connect();
Log.i(TAG, "+++ connected");
isConnected = true;
in = new DataInputStream(clientSocket.getInputStream());
out = new DataOutputStream(clientSocket.getOutputStream());
Log.i(TAG, "+++ streams created");
} catch (IOException e) {
Long sleep = (long) 10000;
Log.e(TAG, "+++ connection failed, sleep for " + sleep);
try {
Thread.sleep(sleep);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
return isConnected;
}
public void run() {
try {
getDevice();
} catch (IOException e) {
Log.e(TAG, "+++ device error " + e.toString());
}
while (isRunning) {
try {
processData();
} catch (Exception e) {
Log.e(TAG, "+++ data error " + e.toString());
}
}
close();
Log.i(TAG, "+++ ending bluetooth run");
}
private void closeSocket() {
if (clientSocket != null)
try {
clientSocket.close();
Log.d(TAG, "+++ socket closed");
} catch (IOException e) {
e.printStackTrace();
}
}
private void closeStreams() {
if (in != null)
try {
in.close();
Log.d(TAG, "+++ input stream closed");
} catch (IOException e) {
Log.e(TAG, "+++ input stream not closed " + e.toString());
}
if (out != null)
try {
out.close();
Log.d(TAG, "+++ output stream closed");
} catch (IOException e) {
Log.e(TAG, "+++ output stream not closed " + e.toString());
}
}
private void close() {
closeStreams();
closeSocket();
isConnected = false;
}
public void stop() {
isRunning = false;
}
public boolean isRunning() {
return isRunning;
}
public void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
private void processData() throws Exception {
try {
String outData = null;
int timer = 0;
while (outData == null) {
if (!connect())
return;
Log.i(TAG, "+++ waiting on queue ");
outData = queue.poll(1, TimeUnit.SECONDS);// .take();
if (timer++ > 15) {
return;
}
}
envelope.sendMessage(outData, out);
String inData = envelope.receiveMessage(in);
Log.i(TAG, "+++ response " + inData);
} catch (Exception e) {
Log.e(TAG, "+++ processData error " + e.toString());
close();
throw e;
}
}
}