0

I'm trying to fix a bug in an app that rarely causes Application Not Responding (ANR).

I followed these steps to find the possible cause: Android - how do I investigate an ANR?

With it I've come across this entry in 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)

This leads me to believe, that the Messenger.send() call in EmotivReaderRunnable.run() is the reason for the ANR. However, I've also noticed that at the beginning of traces.txt it says:

Heap: 0% free, 170MB/170MB; 3813172 objects

Is the full heap a symptom of a problem with the Messenger.send() call or is it rather the other way around: The full heap causes a problem with the said call? In case of the latter, how could I find the reason for the full heap?

Here's the 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();
}

I don't see what could be wrong with my run(). My only guess it that for some reason decryptedPacket is becoming rather large. But the ANR happened once after 2 minutes of recording and once after about 30 minutes. I receive less than 1mb of data per minute. So that should be far from causing any out of memory problems.

Any recommendations on how I can continue from here?

pscl
  • 3
  • 1
  • What thread is the runnable running on? ANR should only occur if something on the UI thread takes too long. Is something on the UI thread processing the result or waiting for this message rather than returning control to the framework? – Gabe Sechan Oct 06 '17 at 15:02
  • If you processes takes more than few seconds, android will consider it as not responding. If it is in main UI thread, app is considered `not responding` in 5 second. If it is service, it takes more time like 20 second. So check where your run is getting called from and verify the time. – Jimmy Oct 06 '17 at 15:04

0 Answers0