应用模具上启动 [英] App dies on startup
问题描述
当我开始我的应用程序,我启动的AsyncTask
做一些下载。这可能需要一段时间。结果
当该线程下载数据,我已经听了位置更新。当我收到一个新的位置,我开始一个新的的AsyncTask
做一些处理。然而,这种类依赖于所下载的数据,因此,它必须等待直到在下载完成:
公共无效的setLocation(地点)抛出IOException
Logger.log(新位置 - 计算最近的车站);
如果(!initialStationsRead){
Logger.log(位置更新等站读);
而(!initialStationsRead)
;
Logger.log(位置更新完成的等待);
}
/ *执行处理* /
}
第一个线程集 initialStationsRead
到真正
当它完成,因此第二个线程后回升。这一切工作正常在我的测试设备。
不过,从我告诉我的应用程序将不会启动用户收到一封电子邮件。加载屏幕出现了,10-12秒后消失无警告。他使用的HTC One秒。
这是他送我的logcat的:
07-05 22:11:04.938:W / dalvikvm(19961):主题ID = 2:暂停#旋2主题ID = 11(PCF = 1)
07-05 22:11:04.938:I / dalvikvm(19961):GC守护PRIO = 5 TID = 2 RUNNABLE
07-05 22:11:04.938:I / dalvikvm(19961):|组=系统SCOUNT = 0 dsCount = 0 = OBJ自我0x40d5c580 = 0x1669ae8
07-05 22:11:04.938:I / dalvikvm(19961):| sysTid = 19965漂亮= 0 =附表0/0 = CGRP默认手柄= 21931384
07-05 22:11:04.938:I / dalvikvm(19961):| schedstat =(0 0 0)UTM = 2 STM = 0核心= 1
07-05 22:11:04.938:I / dalvikvm(19961):在dalvik.system.NativeStart.run(本机方法)
07-05 22:11:04.938:I / dalvikvm(19961):AsyncTask的#3PRIO = 5 TID = 11 RUNNABLE JIT
07-05 22:11:04.938:I / dalvikvm(19961):|组=主SCOUNT = 1 dsCount = 0 = OBJ自我0x40f90588 = 0x1b35b00
07-05 22:11:04.938:I / dalvikvm(19961):| sysTid = 19991漂亮= 0 =附表0/0 = CGRP默认手柄= 29193008
07-05 22:11:04.938:I / dalvikvm(19961):| schedstat =(0 0 0)UTM = 287 STM = 1芯= 1
07-05 22:11:04.938:I / dalvikvm(19961):在com.busybits.treinverkeer.data.Data.setLocation(Data.java:~102)
07-05 22:11:04.938:I / dalvikvm(19961):在com.busybits.treinverkeer.TreinVerkeer $ SetLocationAsyncTask.doInBackground(TreinVerkeer.java:408)
07-05 22:11:04.938:I / dalvikvm(19961):在com.busybits.treinverkeer.TreinVerkeer $ SetLocationAsyncTask.doInBackground(TreinVerkeer.java:1)
07-05 22:11:04.938:I / dalvikvm(19961):在android.os.AsyncTask $ 2.call(AsyncTask.java:264)
07-05 22:11:04.938:I / dalvikvm(19961):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
07-05 22:11:04.938:I / dalvikvm(19961):在java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-05 22:11:04.938:I / dalvikvm(19961):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-05 22:11:04.938:I / dalvikvm(19961):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)
07-05 22:11:04.938:I / dalvikvm(19961):在java.lang.Thread.run(Thread.java:864)
07-05 22:11:05.629:D / WifiStateMachine(436):fetchRssiAndLinkSpeedNative RSSI = -32
07-05 22:11:05.689:W / dalvikvm(19961):主题ID = 2:暂停旋#3主题ID = 11(PCF = 1)
07-05 22:11:05.689:I / dalvikvm(19961):GC守护PRIO = 5 TID = 2 RUNNABLE
07-05 22:11:05.689:I / dalvikvm(19961):|组=系统SCOUNT = 0 dsCount = 0 = OBJ自我0x40d5c580 = 0x1669ae8
07-05 22:11:05.689:I / dalvikvm(19961):| sysTid = 19965漂亮= 0 =附表0/0 = CGRP默认手柄= 21931384
07-05 22:11:05.689:I / dalvikvm(19961):| schedstat =(0 0 0)UTM = 2 STM = 0核心= 1
07-05 22:11:05.689:I / dalvikvm(19961):在dalvik.system.NativeStart.run(本机方法)
07-05 22:11:05.689:I / dalvikvm(19961):AsyncTask的#3PRIO = 5 TID = 11 RUNNABLE JIT
07-05 22:11:05.689:I / dalvikvm(19961):|组=主SCOUNT = 1 dsCount = 0 = OBJ自我0x40f90588 = 0x1b35b00
07-05 22:11:05.689:I / dalvikvm(19961):| sysTid = 19991漂亮= 0 =附表0/0 = CGRP默认手柄= 29193008
07-05 22:11:05.689:I / dalvikvm(19961):| schedstat =(0 0 0)UTM = 362 STM = 1芯= 1
07-05 22:11:05.689:I / dalvikvm(19961):在com.busybits.treinverkeer.data.Data.setLocation(Data.java:~102)
07-05 22:11:05.689:I / dalvikvm(19961):在com.busybits.treinverkeer.TreinVerkeer $ SetLocationAsyncTask.doInBackground(TreinVerkeer.java:408)
07-05 22:11:05.689:I / dalvikvm(19961):在com.busybits.treinverkeer.TreinVerkeer $ SetLocationAsyncTask.doInBackground(TreinVerkeer.java:1)
07-05 22:11:05.689:I / dalvikvm(19961):在android.os.AsyncTask $ 2.call(AsyncTask.java:264)
07-05 22:11:05.689:I / dalvikvm(19961):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
07-05 22:11:05.689:I / dalvikvm(19961):在java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-05 22:11:05.689:I / dalvikvm(19961):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-05 22:11:05.689:I / dalvikvm(19961):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)
07-05 22:11:05.689:I / dalvikvm(19961):在java.lang.Thread.run(Thread.java:864)
07-05 22:11:05.719:D / Skia的(1004):AndroidImageRef [0x2438190] releasePixel失败,因为锁定计数= 1
07-05 22:11:06.439:W / dalvikvm(19961):主题ID = 2:暂停旋#4主题ID = 11(PCF = 1)
07-05 22:11:06.439:I / dalvikvm(19961):GC守护PRIO = 5 TID = 2 RUNNABLE
07-05 22:11:06.439:I / dalvikvm(19961):|组=系统SCOUNT = 0 dsCount = 0 = OBJ自我0x40d5c580 = 0x1669ae8
07-05 22:11:06.439:I / dalvikvm(19961):| sysTid = 19965漂亮= 0 =附表0/0 = CGRP默认手柄= 21931384
07-05 22:11:06.439:I / dalvikvm(19961):| schedstat =(0 0 0)UTM = 2 STM = 0核心= 1
07-05 22:11:06.439:I / dalvikvm(19961):在dalvik.system.NativeStart.run(本机方法)
07-05 22:11:06.439:I / dalvikvm(19961):AsyncTask的#3PRIO = 5 TID = 11 RUNNABLE JIT
07-05 22:11:06.439:I / dalvikvm(19961):|组=主SCOUNT = 1 dsCount = 0 = OBJ自我0x40f90588 = 0x1b35b00
07-05 22:11:06.439:I / dalvikvm(19961):| sysTid = 19991漂亮= 0 =附表0/0 = CGRP默认手柄= 29193008
07-05 22:11:06.439:I / dalvikvm(19961):| schedstat =(0 0 0)UTM = 437 STM = 1芯= 1
07-05 22:11:06.439:I / dalvikvm(19961):在com.busybits.treinverkeer.data.Data.setLocation(Data.java:~102)
07-05 22:11:06.439:I / dalvikvm(19961):在com.busybits.treinverkeer.TreinVerkeer $ SetLocationAsyncTask.doInBackground(TreinVerkeer.java:408)
07-05 22:11:06.439:I / dalvikvm(19961):在com.busybits.treinverkeer.TreinVerkeer $ SetLocationAsyncTask.doInBackground(TreinVerkeer.java:1)
07-05 22:11:06.439:I / dalvikvm(19961):在android.os.AsyncTask $ 2.call(AsyncTask.java:264)
07-05 22:11:06.439:I / dalvikvm(19961):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
07-05 22:11:06.439:I / dalvikvm(19961):在java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-05 22:11:06.439:I / dalvikvm(19961):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-05 22:11:06.439:I / dalvikvm(19961):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)
07-05 22:11:06.439:I / dalvikvm(19961):在java.lang.Thread.run(Thread.java:864)
这是重复x次。
现在, Data.java:102
是行而(!initialStationsRead)
,所以必须走什么不对劲的地方。
这是怎么回事,我怎么能解决这个问题?
当它完成,因此第二个线程后拿起第一个线程设置initialStationsRead为true。
块引用>忙循环是邪恶的化身。如果我有圣水得心应手,你会是相当潮湿的现在。 : - )
(这也意味着我有很好的圣 - 水投掷目标长距离,这可能并非如此)
Java有足够的线程同步选项,并让他们在十年加,从低层次的
等待()
和通知()
在对象
到的java.util.concurrent
构造,如旗语
。选择一个,并用它,摆脱繁忙的循环。或者,跟踪Jan-亨克的意见,并做这项工作连续在同一线程上,基于一个标志。
任何想法,但为什么出现这种情况了设备上,而不是我的或其他人的设备我知道吗?
块引用>那么,对于初学者来说,一个S是双核的,所以你的线程实际上可能在同一时间(每个核心一个)运行。线程问题将更有可能在多核环境中浮出水面。
此外,Angelo的答案 - 我在写这贴时 - 值得一提的
。When I start my app, I start an
AsyncTask
to do some downloading. This can take a while.
When that thread is downloading the data, I am already listening for location updates. When I receive a new location, I start a newAsyncTask
to do some processing. However, this class depends on the downloaded data, so it has to wait until the downloading is done:public void setLocation(Location location) throws IOException { Logger.log("New location - calculating nearest stations"); if (!initialStationsRead) { Logger.log("Location update waiting for stations to be read"); while (!initialStationsRead) ; Logger.log("Location update done waiting"); } /* Do the processing */ }
The first thread sets
initialStationsRead
totrue
when it's done, so the second thread can pick up after that. This all works fine on my test devices.However, I received an email from a user telling me that the app won't start. The loading screen appeared, and after 10-12 seconds disappeared without a warning. He uses a HTC One S.
This is the logcat he sent me:
07-05 22:11:04.938: W/dalvikvm(19961): threadid=2: spin on suspend #2 threadid=11 (pcf=1) 07-05 22:11:04.938: I/dalvikvm(19961): "GC" daemon prio=5 tid=2 RUNNABLE 07-05 22:11:04.938: I/dalvikvm(19961): | group="system" sCount=0 dsCount=0 obj=0x40d5c580 self=0x1669ae8 07-05 22:11:04.938: I/dalvikvm(19961): | sysTid=19965 nice=0 sched=0/0 cgrp=default handle=21931384 07-05 22:11:04.938: I/dalvikvm(19961): | schedstat=( 0 0 0 ) utm=2 stm=0 core=1 07-05 22:11:04.938: I/dalvikvm(19961): at dalvik.system.NativeStart.run(Native Method) 07-05 22:11:04.938: I/dalvikvm(19961): "AsyncTask #3" prio=5 tid=11 RUNNABLE JIT 07-05 22:11:04.938: I/dalvikvm(19961): | group="main" sCount=1 dsCount=0 obj=0x40f90588 self=0x1b35b00 07-05 22:11:04.938: I/dalvikvm(19961): | sysTid=19991 nice=0 sched=0/0 cgrp=default handle=29193008 07-05 22:11:04.938: I/dalvikvm(19961): | schedstat=( 0 0 0 ) utm=287 stm=1 core=1 07-05 22:11:04.938: I/dalvikvm(19961): at com.busybits.treinverkeer.data.Data.setLocation(Data.java:~102) 07-05 22:11:04.938: I/dalvikvm(19961): at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:408) 07-05 22:11:04.938: I/dalvikvm(19961): at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:1) 07-05 22:11:04.938: I/dalvikvm(19961): at android.os.AsyncTask$2.call(AsyncTask.java:264) 07-05 22:11:04.938: I/dalvikvm(19961): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 07-05 22:11:04.938: I/dalvikvm(19961): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 07-05 22:11:04.938: I/dalvikvm(19961): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 07-05 22:11:04.938: I/dalvikvm(19961): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 07-05 22:11:04.938: I/dalvikvm(19961): at java.lang.Thread.run(Thread.java:864) 07-05 22:11:05.629: D/WifiStateMachine(436): fetchRssiAndLinkSpeedNative RSSI = -32 07-05 22:11:05.689: W/dalvikvm(19961): threadid=2: spin on suspend #3 threadid=11 (pcf=1) 07-05 22:11:05.689: I/dalvikvm(19961): "GC" daemon prio=5 tid=2 RUNNABLE 07-05 22:11:05.689: I/dalvikvm(19961): | group="system" sCount=0 dsCount=0 obj=0x40d5c580 self=0x1669ae8 07-05 22:11:05.689: I/dalvikvm(19961): | sysTid=19965 nice=0 sched=0/0 cgrp=default handle=21931384 07-05 22:11:05.689: I/dalvikvm(19961): | schedstat=( 0 0 0 ) utm=2 stm=0 core=1 07-05 22:11:05.689: I/dalvikvm(19961): at dalvik.system.NativeStart.run(Native Method) 07-05 22:11:05.689: I/dalvikvm(19961): "AsyncTask #3" prio=5 tid=11 RUNNABLE JIT 07-05 22:11:05.689: I/dalvikvm(19961): | group="main" sCount=1 dsCount=0 obj=0x40f90588 self=0x1b35b00 07-05 22:11:05.689: I/dalvikvm(19961): | sysTid=19991 nice=0 sched=0/0 cgrp=default handle=29193008 07-05 22:11:05.689: I/dalvikvm(19961): | schedstat=( 0 0 0 ) utm=362 stm=1 core=1 07-05 22:11:05.689: I/dalvikvm(19961): at com.busybits.treinverkeer.data.Data.setLocation(Data.java:~102) 07-05 22:11:05.689: I/dalvikvm(19961): at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:408) 07-05 22:11:05.689: I/dalvikvm(19961): at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:1) 07-05 22:11:05.689: I/dalvikvm(19961): at android.os.AsyncTask$2.call(AsyncTask.java:264) 07-05 22:11:05.689: I/dalvikvm(19961): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 07-05 22:11:05.689: I/dalvikvm(19961): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 07-05 22:11:05.689: I/dalvikvm(19961): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 07-05 22:11:05.689: I/dalvikvm(19961): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 07-05 22:11:05.689: I/dalvikvm(19961): at java.lang.Thread.run(Thread.java:864) 07-05 22:11:05.719: D/skia(1004): AndroidImageRef[ 0x2438190 ] releasePixel fail as lockCount=1 07-05 22:11:06.439: W/dalvikvm(19961): threadid=2: spin on suspend #4 threadid=11 (pcf=1) 07-05 22:11:06.439: I/dalvikvm(19961): "GC" daemon prio=5 tid=2 RUNNABLE 07-05 22:11:06.439: I/dalvikvm(19961): | group="system" sCount=0 dsCount=0 obj=0x40d5c580 self=0x1669ae8 07-05 22:11:06.439: I/dalvikvm(19961): | sysTid=19965 nice=0 sched=0/0 cgrp=default handle=21931384 07-05 22:11:06.439: I/dalvikvm(19961): | schedstat=( 0 0 0 ) utm=2 stm=0 core=1 07-05 22:11:06.439: I/dalvikvm(19961): at dalvik.system.NativeStart.run(Native Method) 07-05 22:11:06.439: I/dalvikvm(19961): "AsyncTask #3" prio=5 tid=11 RUNNABLE JIT 07-05 22:11:06.439: I/dalvikvm(19961): | group="main" sCount=1 dsCount=0 obj=0x40f90588 self=0x1b35b00 07-05 22:11:06.439: I/dalvikvm(19961): | sysTid=19991 nice=0 sched=0/0 cgrp=default handle=29193008 07-05 22:11:06.439: I/dalvikvm(19961): | schedstat=( 0 0 0 ) utm=437 stm=1 core=1 07-05 22:11:06.439: I/dalvikvm(19961): at com.busybits.treinverkeer.data.Data.setLocation(Data.java:~102) 07-05 22:11:06.439: I/dalvikvm(19961): at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:408) 07-05 22:11:06.439: I/dalvikvm(19961): at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:1) 07-05 22:11:06.439: I/dalvikvm(19961): at android.os.AsyncTask$2.call(AsyncTask.java:264) 07-05 22:11:06.439: I/dalvikvm(19961): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 07-05 22:11:06.439: I/dalvikvm(19961): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 07-05 22:11:06.439: I/dalvikvm(19961): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 07-05 22:11:06.439: I/dalvikvm(19961): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 07-05 22:11:06.439: I/dalvikvm(19961): at java.lang.Thread.run(Thread.java:864)
This is repeated x times.
Now,
Data.java:102
is the linewhile(!initialStationsRead)
, so there must be going something wrong there.What is happening, and how can I solve this?
解决方案The first thread sets initialStationsRead to true when it's done, so the second thread can pick up after that.
Busy loops are evil incarnate. If I had holy water handy, you'd be rather wet right now. :-)
(that also implies that I have really good holy-water throwing aim over long distances, which probably isn't the case)
Java has plenty of options for thread synchronization, and has had them for a decade-plus, from the low-level
wait()
andnotify()
onObject
to thejava.util.concurrent
constructs likeSemaphore
. Pick one and use it, getting rid of the busy loop.Or, follow Jan-Henk's advice and do the work serially on the same thread, based on a flag.
Any idea though why this happens on his device and not on mine or devices of other people i know?
Well, for starters, the One S is dual-core, and so your threads may actually be running at the same time (one per core). Threading problems will be more likely to surface in multi-core environments.
Also, Angelo's answer -- posted while I was writing this -- is worth noting.
这篇关于应用模具上启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!