我正在尝试修复很少导致应用无响应(ANR)的应用中的错误。
我按照以下步骤查找可能的原因: Android - how do I investigate an ANR?
有了它,我在traces.txt中遇到了这个条目:
"Emotiv USB dongle reading thread" prio=5 tid=29 Suspended
| group="main" sCount=1 dsCount=0 obj=0x32c077c0 self=0xa21de800
| sysTid=21942 nice=0 cgrp=default sched=0/0 handle=0xaf4e4000
| state=S schedstat=( 661311503042 260341162486 616738 ) utm=64211 stm=1920 core=3 HZ=100
| stack=0xa043e000-0xa0440000 stackSize=1036KB
| held mutexes=
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:353)
- locked <0x2985cad6> (a android.os.MessageQueue)
at android.os.Handler.enqueueMessage(Handler.java:631)
at android.os.Handler.sendMessageAtTime(Handler.java:600)
at android.os.Handler.sendMessageDelayed(Handler.java:570)
at android.os.Handler.sendMessage(Handler.java:507)
at android.os.Handler$MessengerImpl.send(Handler.java:721)
at android.os.Messenger.send(Messenger.java:57)
at eeg_presentation_app.Driver.EmotivReaderRunnable.run(EmotivReaderRunnable.java:109)
at java.lang.Thread.run(Thread.java:818)
这让我相信,Messenger.send()
中的EmotivReaderRunnable.run()
电话是ANR的原因。
但是,我也注意到在traces.txt的开头它说:
Heap: 0% free, 170MB/170MB; 3813172 objects
完整堆是Messenger.send()
调用问题的症状,还是反过来说:完整堆会导致上述调用出现问题?如果是后者,我怎么能找到完整堆的原因?
这里是EmotivReaderRunnable.run():
public void run() {
/**
* set up connection to EEG
*/
final UsbInterface myInterface = device.getInterface(1); // communicate with interface 1
final UsbEndpoint myEndpoint = myInterface.getEndpoint(0); // endpoint for communication
UsbDeviceConnection connection = usbManager.openDevice(device); // start connection
connection.claimInterface(myInterface, true);
/**
* buffer for packet as it arrives, split up in bytes (encrypted)
*/
ByteBuffer encryptedPacket = ByteBuffer.wrap(new byte[32]);
UsbRequest usbRequest = new UsbRequest();
UsbRequest usbResult = null;
// initialize connection
usbRequest.initialize(connection, myEndpoint);
//as long as thread active
while (!Thread.interrupted()) {
// read 32 byte data into encryptedPacket, return true if successful
boolean success = usbRequest.queue(encryptedPacket, 32);
if (success) {
// get result of usbRequest
usbResult = connection.requestWait();
} else {
break; //something is wrong with the connection
}
// now packet was written to encryptedPacket
if (encryptedPacket.position() == 0) { //no content
break;
}
// how long since system was booted
long elapsedNanos = SystemClock.elapsedRealtimeNanos(); //this requires api level 17 (android 4.2)
//long elapsedNanos = SystemClock.elapsedRealtime(); //temporary, for debugging on my Android 4.1
// it allows very exact timing
// standard wall clock time -> time when packet was received
long receivedTime = System.currentTimeMillis();
// decrypt packet content with EmotivDecryptor
byte[] decryptedPacket = decryptor.decrypt(encryptedPacket.array());
Message message = Message.obtain();
message.setData(packetToBundle(elapsedNanos, receivedTime, decryptedPacket));
try {
messenger.send(message);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in run()");
e.printStackTrace();
break; // the service went away, so let's close this thread as well
}
}
if (usbResult != null) {
usbResult.close();
}
connection.releaseInterface(myInterface);
connection.close();
}
我不知道run()
可能出现的问题。我唯一猜测由于某种原因decryptedPacket
变得相当大。但ANR在记录2分钟后发生一次,在约30分钟后发生一次。我每分钟收到的数据不到1mb。所以这应该远远不会造成任何内存不足的问题。
关于如何从这里继续的任何建议?