错误:每个线程只能创建一个Looper,其堆栈跟踪没有"引起:"

时间:2017-06-16 22:32:06

标签: android multithreading

我使用Extending the Service class中的代码来处理两个服务和另一个类(不是服务)中的消息传递。

下面是初始化和获取可疑对象的代码(服务中onCreate()中的每个线程,另一个类中的静态方法中有2个线程)。没有透明地调用thread.run()(因为它不应该是,但我知道我可以通过在调用thread.start()之后调用它而不是通过调用thread.start()两次来实现崩溃) 。虽然此代码来自Android文档,但我只更改了实现中的一些变量名称。对依赖于此的消息处理代码也是如此。

        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);

这是堆栈跟踪。不幸的是,没有任何迹象表明我的代码中的哪个实现是违法者,而且我无法重现崩溃。

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

似乎某种程度上,某些Android为什么不应该调用thread.run(),但我不知道怎么知道触发它的是什么。我已经查看过建议覆盖run()的其他问题和答案,以防止这种情况发生(例如https://stackoverflow.com/a/24115631/1493426),但我不知道如何通过扩展HandlerThread来实现这一点。合理的方式,不会产生不良的,意想不到的后果。

现在我倾向于独自离开,因为代码已经存在至少几个月了,这次崩溃只见过一次,但我想知道是否有&#39 ;一种安全的方法,使代码更具防撞性,而不会隐藏任何潜在的问题。

0 个答案:

没有答案