应用程序在启动时死亡

时间:2012-07-05 21:02:50

标签: android

当我启动我的应用时,我开始AsyncTask进行一些下载。这可能需要一段时间 当该线程正在下载数据时,我已经在监听位置更新。当我收到新位置时,我会开始新的AsyncTask进行一些处理。但是,此类取决于下载的数据,因此必须等到下载完成后才能执行此操作:

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 */
}

第一个线程在完成时将initialStationsRead设置为true,因此第二个线程可以在此之后接收。这一切都可以在我的测试设备上正常工作。

但是,我收到了一位用户的电子邮件,告诉我该应用无法启动。加载屏幕出现,10-12秒后消失,没有警告。他使用的是HTC One S.

这是他寄给我的logcat:

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)

重复x次。

现在,Data.java:102while(!initialStationsRead)行,所以必定会出错。

发生了什么,我该如何解决?

2 个答案:

答案 0 :(得分:3)

  

第一个线程在完成后将initialStationsRead设置为true,因此第二个线程可以在此之后接收。

忙碌的循环是邪恶的化身。如果我有方便的圣水,你现在就会变得很湿。 : - )

(这也意味着我有很长距离的圣水投掷目标,这可能不是这样)

Java有很多用于线程同步的选项,从wait()上的低级notify()Objectjava.util.concurrent已有十多年的选择权。像Semaphore这样的结构。选择一个并使用它,摆脱繁忙的循环。

或者,按照Jan-Henk的建议,根据旗帜在同一个帖子上连续完成工作。

  

不知道为什么会在他的设备上发生这种情况,而不是我自己或我认识的其他人的设备?

嗯,对于初学者来说,One S是双核的,所以你的线程实际上可能同时运行(每个核心一个)。线程问题将更有可能在多核环境中浮现。

另外,Angelo的回答 - 在我写这篇文章时发布 - 值得注意。

答案 1 :(得分:0)

我不知道这是否有帮助但请记住,在HoneyCombAndroid 3.0)之后和Donut之前(Android 1.6)只有一个AsyncTask可以同时运行,因为AsyncTask使用线程池模式,并且这些版本上的默认线程池大小为1.如果您希望AsyncTasks同时在这些版本的{{1}中同时运行},您可以使用标记Android来使用此代码executeOnExecutor(Executor, Params...)。有关详细信息,请参阅此答案of this previous post。看到拥有THREAD_POOL_EXECUTOR设备的用户运行HTC One S,这可能是您问题的根源。