1

I'm using code from Extending the Service class to handle messaging in two Services and in another class (that's not a Service).

Below is the code that initializes and gets the suspicious objects (one thread each in onCreate() in the Services, and 2 threads in a static method in the other class). Nowhere is thread.run() explicitly called (as it shouldn't be, but I know that I can make the crash happen by calling it after calling thread.start() but not by calling thread.start() twice). While this code is taken from the Android documentation, I've only altered some of the variable names in my implementation. The same is true of the message-handling code that relies on this.

        HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();

        // Get the HandlerThread's Looper and use it for our Handler
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);

Here's the stacktrace. Unfortunately, there's nothing indicating which implementation in my code is the offender, and I'm not able to reproduce the crash.

Fatal Exception: java.lang.RuntimeException: Only one Looper may be created per thread
   at android.os.Looper.prepare(Looper.java:89)
   at android.os.Looper.prepare(Looper.java:84)
   at android.os.HandlerThread.run(HandlerThread.java:54)
   06-15 06:23:18.599 27561-29056/? E/BluetoothBoundService﹕ Interrupted 
   read:
   java.lang.InterruptedException
   at java.lang.Thread.sleep(Native Method)
   at java.lang.Thread.sleep(Thread.java:371)
   at java.lang.Thread.sleep(Thread.java:313)
   at services.BluetoothBoundService.receiveDataFromBT                      
   (BluetoothBoundService.java:1442)
   at 
  services.BluetoothBoundService.access$2700(BluetoothBoundService.java:147)
   at services.BluetoothBoundService$9.run(BluetoothBoundService.java:1173)
   at java.lang.Thread.run(Thread.java:761)
   06-15 06:23:18.898 28954-28975/? E/BluetoothRemoteDevices﹕        
   state12newState1
   06-15 06:23:23.469 27561-27570/? E/System﹕ Uncaught exception thrown by        
   finalizer
   06-15 06:23:23.470 27561-27570/? E/System﹕ java.io.IOException: socket 
   not created
   at android.net.LocalSocketImpl.shutdownInput(LocalSocketImpl.java:404)
   at android.net.LocalSocket.shutdownInput(LocalSocket.java:207)
   at android.bluetooth.BluetoothSocket.close(BluetoothSocket.java:575)
   at android.bluetooth.BluetoothSocket.finalize(BluetoothSocket.java:273)
   at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:222)
   at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:209)
   at java.lang.Thread.run(Thread.java:761)
   06-15 06:23:24.112 15861-15861/? E/SearchServiceStarter﹕ Task 174 failed        
   or timed out. Client 69758913221593243 disconnecting from SearchService!
   java.util.concurrent.CancellationException: Task was cancelled.
   at com.google.common.util.concurrent.d.ct(SourceFile:75)
   at com.google.common.util.concurrent.d.get(SourceFile:57)
   at com.google.common.util.concurrent.cg.n(SourceFile:2)
   at com.google.common.util.concurrent.av.l(SourceFile:50)
   at com.google.common.util.concurrent.ax.run(SourceFile:5)
   at 
   com.google.android.apps.gsa.shared.util.concurrent.a.bc.run(SourceFile:2)
   at android.os.Handler.handleCallback(Handler.java:751)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6119)
   at java.lang.reflect.Method.invoke(Native Method)
   at        
   com.android....ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
   06-15 06:23:24.144 15861-15861/? E/WorkerRegistryImpl﹕ getWorker() is        
   called after WorkerRegistry disposal.
   06-15 06:23:24.153 15861-15861/? E/WorkerRegistryImpl﹕ getWorker() is               
   called after WorkerRegistry disposal.
   06-15 06:23:34.229 15861-15861/? E/SearchServiceStarter﹕ Task 174 failed               
   or timed out. Client 69758913221593244 disconnecting from SearchService!
   java.util.concurrent.CancellationException: Task was cancelled.
   at com.google.common.util.concurrent.d.ct(SourceFile:75)
   at com.google.common.util.concurrent.d.get(SourceFile:57)
   at com.google.common.util.concurrent.cg.n(SourceFile:2)
   at com.google.common.util.concurrent.av.l(SourceFile:50)
   at com.google.common.util.concurrent.ax.run(SourceFile:5)
   at 
   com.google.android.apps.gsa.shared.util.concurrent.a.bc.run(SourceFile:2)
   at android.os.Handler.handleCallback(Handler.java:751)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6119)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(Zy

It seems that somehow and somewhy Android is calling thread.run() when it shouldn't be, but I don't know how to tell what's triggering that. I've looked at the other questions and answers that propose overriding run() to prevent this from happening (for example https://stackoverflow.com/a/24115631/1493426), but I don't see how to do that by extending HandlerThread in a reasonable way that won't have undesirable, unintended consequences.

For now I'm inclined to leave everyting alone, since the code has been around for at least several months, and this crash has only been seen once, but I'd like to know if there's a safe way to make the code more crash proof without hiding any underlying problems.

hBrent
  • 1,696
  • 1
  • 17
  • 38
  • 1
    The source code for HandlerThread (https://android.googlesource.com/platform/frameworks/base/+/nougat-mr2-release/core/java/android/os/HandlerThread.java#51) is pretty straightforward. It's hard to see what would cause this outside of a thread-local-storage glitch. – fadden Jun 16 '17 at 22:56
  • Is that the full stack trace? Are you sure there aren't any other `Caused by:` portions beneath the part you posted? – Karakuri Jun 17 '17 at 01:32
  • @Karakuri I thought that was the whole stack trace, but apparently that's not the case. (I didn't observe this crash myself and didn't realize there was more documentation in the problem ticket until I looked again.) I'll update the question with more of the stack trace. There was no `Caused by:`, in it, though. – hBrent Jun 19 '17 at 16:23

0 Answers0