为什么我在Messenger.send()上获得Android应用程序无响应(ANR)?

时间:2017-10-06 14:57:54

标签: java android

我正在尝试修复很少导致应用无响应(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。所以这应该远远不会造成任何内存不足的问题。

关于如何从这里继续的任何建议?

0 个答案:

没有答案