- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在向我的 Pebble 发送大量数据,但有些数据一直被丢弃。我意识到这部分是由于缓冲区大小不足以容纳我发送的 PebbleDictionary
,所以我将它分成多个小的。但是,这引入了出现 APP_MSG_BUSY
错误的问题。
这可能会发生,因为我不是在等待来自卵石的 ack/nack,而是只是来回发送数据。因此,我尝试添加 ack/nack 处理程序以及一个队列,但由于我的 sendMessage()
函数在等待 ack/nack 处理程序时阻塞了主 UI 线程,所以我无法让它工作.
因此,我的问题是处理 APP_MSG_BUSY
的这个特定实例的最佳方法是什么。我不希望我发送的任何数据被丢弃,所以这意味着要么在发送下一条数据之前等待确认,要么在收到 nack 后重新发送。如果可能的话,我想避免使用线程,但我一直无法想出一个不涉及线程的合理解决方案。
编辑:据我所知,pebble 代码中没有错误。它会使用正确的 key 请求数据,并且会(自动)确认 android 应用程序发送的任何消息。
如果你愿意,我已经在下面发布了我的代码:
当前代码(android 应用的相关部分):
public class MainActivity extends ActionBarActivity {
private PebbleDataReceiver mReceiver;
private PebbleAckReceiver ackReceiver;
private PebbleNackReceiver nackReceiver;
ConcurrentLinkedQueue<BoolDictionary> queue = new ConcurrentLinkedQueue<BoolDictionary>();
final UUID PEBBLE_APP_UUID = UUID.fromString("2ef1h2ba-1a59-41f7-87da-797beca4d395");
final static int CONTACTS_NEEDED = 0x0;
final static int CONTACTS_SIZE = 0x1;
final static int NEW_MESSAGE = 0x2;
final static int NEW_CONVERSATION = 0x3;
final static int RECORD_NEW_MESSAGE = 0x4;
Thread sendMessages = new Thread(){
public void run(){
while (true){
PebbleKit.sendDataToPebbleWithTransactionId(getApplicationContext(), PEBBLE_APP_UUID, queue.element().getDict(), queue.element().getTransId());
try {
queue.element().wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
}
if (queue.element().isAkced()){
break;
}
}
queue.remove();
if (queue.size() > 0){
run();
}
else if (queue.size() == 0){
queue.element().wait();
}
}
};
public BoolDictionary createBoolDictionary(int key, int data){
PebbleDictionary dict = new PebbleDictionary();
dict.addInt32(key, data);
return new BoolDictionary(dict);
}
public BoolDictionary createBoolDictionary(int key, String data){
PebbleDictionary dict = new PebbleDictionary();
dict.addString(key, data);
return new BoolDictionary(dict);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendMessages.start();
ackReceiver = new PebbleAckReceiver(PEBBLE_APP_UUID) {
@Override
public void receiveAck(Context context, int transactionId) {
if (queue.element().getTransId() == transactionId){
queue.element().setAkced(true);
queue.element().notifyAll();
}
}
};
nackReceiver = new PebbleNackReceiver(PEBBLE_APP_UUID){
@Override
public void receiveNack(Context context, int transactionId) {
if (queue.element().getTransId() == transactionId){
queue.element().setAkced(false);
queue.element().notifyAll();
}
}
};
mReceiver = new PebbleDataReceiver(PEBBLE_APP_UUID) {
@Override
public void receiveData(Context context, int transactionId, PebbleDictionary data) {
PebbleKit.sendAckToPebble(context, transactionId);
if (data.contains(CONTACTS_NEEDED)){
//test data
queue.add(createBoolDictionary(0x5, "Entry 1"));
queue.add(createBoolDictionary(0x6, "Entry 2"));
queue.add(createBoolDictionary(0x7, "Entry 3"));
queue.add(createBoolDictionary(0x8, "Entry 4"));
queue.add(createBoolDictionary(0x9, "Entry 5"));
queue.element().notifyAll();
}
}
};
PebbleKit.registerReceivedDataHandler(this, mReceiver);
PebbleKit.registerReceivedAckHandler(this, ackReceiver);
PebbleKit.registerReceivedNackHandler(this, nackReceiver);
}
@Override
protected void onPause(){
super.onPause();
unregisterReceiver(mReceiver);
unregisterReceiver(ackReceiver);
unregisterReceiver(nackReceiver);
}
}
boolean 字典:
public class BoolDictionary extends PebbleDictionary{
private PebbleDictionary dict;
private boolean akced = false;
private int transId;
BoolDictionary(PebbleDictionary data){
this.setDict(data);
setTransId(new Random().nextInt(Integer.MAX_VALUE));
}
[insert getters and setters here]
}
这会产生以下错误:
07-01 10:43:06.096: E/AndroidRuntime(21941): FATAL EXCEPTION: Thread-5310
07-01 10:43:06.096: E/AndroidRuntime(21941): Process: com.example.firstapp, PID: 21941
07-01 10:43:06.096: E/AndroidRuntime(21941): java.util.NoSuchElementException
07-01 10:43:06.096: E/AndroidRuntime(21941): at java.util.AbstractQueue.element(AbstractQueue.java:107)
07-01 10:43:06.096: E/AndroidRuntime(21941): at com.example.firstapp.MainActivity$1.run(MainActivity.java:366)
最佳答案
错误 APP_MSG_BUSY
当 Pebble 收到您的新数据包但蓝牙缓冲区中已经有一条消息表明您的应用还没有时间读取时返回。
要理解这一点,您需要记住 Pebble 上的内存紧张,因此系统无法缓冲传入的消息,因为这会很快占用大量内存。相反,它拒绝该消息。
避免此问题的最佳策略是在发送另一条消息之前等待来自 Pebble 的 ACK/NACK。看起来你已经这样做了,但另一个提示是确保你将多个键分组在一条消息中,而不是为每个键发送一条消息(这最大限度地利用了传入缓冲区,但当然限制是该缓冲区的大小).
关于java - 如何正确处理pebble中的APP_MSG_BUSY?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24513243/
我是一名优秀的程序员,十分优秀!